CAS做單點登陸(SSO)——集成Java Web 項目

添加cas-client的jar包

下載cas-client,地址:http://www.ja-sig.org/downloads/cas-clients/當前最新版本是cas-client-3.2.1-release.zip然後解壓cas-client-3.2.1-release.zip,在modules拷貝cas-client-core-3.2.1.jar應用的WEB-INF/lib目錄中

撰寫支持CAS集成的客戶化包

除了在web.xml添加CAS內置的filter外(具體看配置web.xml),我們需要撰寫自己支持CAS集成的客戶化包。大致思路如下:

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		
		HttpServletRequest request = (HttpServletRequest)servletRequest;
		HttpServletResponse response = (HttpServletResponse)servletResponse;
		
		HttpSession session = request.getSession();
		//在session中自定義一個參數,以它來校驗是否完成過自動登陸
		Object user_login = session.getAttribute(AURORA_USER_LOGIN);
		if (user_login != null){
			//登陸過,就繼續執行其他filter
			filterChain.doFilter(request, response);
			return;
		}
		//通過CAS的API獲得登陸賬號
		String loginName = AssertionHolder.getAssertion().getPrincipal().getName();
		try {
			//執行本系統的登陸。跟平常同時校驗用戶名和密碼不同,這裏只有用戶名。
			executeLoginProc(request,response,loginName);
		} catch (Exception e) {
			logger.log(Level.SEVERE, "executeLoginProc error:", e);
			return;
		}
		//登陸成功
		session.setAttribute(AURORA_USER_LOGIN, Boolean.TRUE);
		//跳轉到登陸成功後的頁面
		response.sendRedirect(roleSelectPageUrl);
	}

把這個class打包成一個jar拷貝到應用的WEB-INF/lib目錄中

如果有興趣,還可以簡單瞭解下org.jasig.cas.client.authentication.AuthenticationFilter這個CAS內置filter的功能

public final void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {     HttpServletRequest request = (HttpServletRequest)servletRequest;     HttpServletResponse response = (HttpServletResponse)servletResponse;     HttpSession session = request.getSession(false);  //檢查自定義屬性"_const_cas_assertion_"     Assertion assertion = session != null ? (Assertion)session.getAttribute("_const_cas_assertion_") : null;

    if (assertion != null) {    //已經成功登陸過CAS       filterChain.doFilter(request, response);       return;     }   //拿到url,並檢查url參數中的ticket是否有效     String serviceUrl = constructServiceUrl(request, response);     String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());     boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);

    if ((CommonUtils.isNotBlank(ticket)) || (wasGatewayed)) {    //ticket有效       filterChain.doFilter(request, response);       return;     }

    this.log.debug("no ticket and no assertion found");     String modifiedServiceUrl;     String modifiedServiceUrl;     if (this.gateway) {       this.log.debug("setting gateway attribute in session");       modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);     } else {       modifiedServiceUrl = serviceUrl;     }

    if (this.log.isDebugEnabled()) {       this.log.debug("Constructed service url: " + modifiedServiceUrl);     }

    String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);

    if (this.log.isDebugEnabled()) {       this.log.debug("redirecting to \"" + urlToRedirectTo + "\"");     }   //重定向到cas的登陸頁面     response.sendRedirect(urlToRedirectTo);   }


 

修改web.xml

在應用WEB-INF/web.xml添加filter的內容,效果如下所示

<!-- ======================== 單點登錄開始 ======================== -->
	<!-- 用於單點退出,該過濾器用於實現單點登出功能,可選配置-->
	<listener>
		<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
	</listener>

	<!-- 該過濾器用於實現單點登出功能,可選配置。 -->
	<filter>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Single Sign Out Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 該過濾器負責用戶的認證工作,必須啓用它 -->
	<filter>
		<filter-name>CASFilter</filter-name>
		<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
		<init-param>
			<param-name>casServerLoginUrl</param-name>
			<param-value>https://sso.aurora-framework.org:8080/cas/login</param-value>
			<!--這裏的server是服務端的IP-->
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>https://sso.aurora-framework.org:8080</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CASFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- 該過濾器負責對Ticket的校驗工作,必須啓用它 -->
	<filter>
		<filter-name>CAS Validation Filter</filter-name>
		<filter-class>
			org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
		<init-param>
			<param-name>casServerUrlPrefix</param-name>
			<param-value>https://sso.aurora-framework.org:8080/cas</param-value>
		</init-param>
		<init-param>
			<param-name>serverName</param-name>
			<param-value>https://sso.aurora-framework.org:8080</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CAS Validation Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--
		該過濾器負責實現HttpServletRequest請求的包裹,
		比如允許開發者通過HttpServletRequest的getRemoteUser()方法獲得SSO登錄用戶的登錄名,可選配置。
	-->
	<filter>
		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<filter-class>
			org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!--
		該過濾器使得開發者可以通過org.jasig.cas.client.util.AssertionHolder來獲取用戶的登錄名。
		比如AssertionHolder.getAssertion().getPrincipal().getName()。
	-->
	<filter>
		<filter-name>CAS Assertion Thread Local Filter</filter-name>
		<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>CAS Assertion Thread Local Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!-- 自動根據單點登錄的結果設置本系統的用戶信息-->
	<filter>
		<display-name>AutoSetUserAdapterFilter</display-name>
		<filter-name>AutoSetUserAdapterFilter</filter-name>
		<filter-class>aurora.plugin.sso.cas.AutoSetUserFilter</filter-class>
		<init-param>
			<param-name>roleSelectPageUrl</param-name>
			<param-value>https://sso.aurora-framework.org:8080/yourapp/role_select.screen</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>AutoSetUserAdapterFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- ======================== 單點登錄結束 ======================== -->

 

前面幾個都是CAS標準配置,最後一個AutoSetUserAdapterFilter(自定義,可以取其他任意名字)纔是我們支持cas的客戶化程序。其中roleSelectPageUrl是指用戶完成單點登錄後跳轉的頁面

本文檔撰寫時java web項目和CAS用同一個tomcat,所以都用的https。否則只需要配置CAS的鏈接爲HTTPS,本項目連接用HTTP。

 

修改CAS的認證邏輯

CAS默認的邏輯是用戶名和密碼一致就可以登陸,現在需要把原web系統的用戶名和密碼校驗挪到CAS中。這裏假設原先web系統中有一張sys_user表存儲了用戶名和MD5散列後的密碼。

 

打開cas/WEB-INF/deployerConfigContext.xml

  1. 註釋掉SimpleTestUsernamePasswordAuthenticationHandler這個Handler,並添加

     

    <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
    	<property ref="dataSource" name="dataSource"></property>
    	<property name="sql" value="select t.encrypted_user_password from sys_user t where t.user_name=?"></property>                     
    	<property ref="MD5PasswordEncoder" name="passwordEncoder"></property>
    </bean>


     

  2.  在文件末尾之前加入數據庫的鏈接:

        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName">
                <value>oracle.jdbc.driver.OracleDriver</value>
            </property>
            <property name="url">
                <value>jdbc:oracle:thin:@yourIP:1521:yourOracleInstanceId</value>
            </property>
            <property name="username">
                <value>yourName</value>
            </property>
            <property name="password">
                <value>yourPassword</value>
            </property>
        </bean>
        <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">
            <constructor-arg index="0">
                <value>MD5</value>
            </constructor-arg>
        </bean>

     

  3. cas加入jdbc支持
    複製cas-server-3.5.2\modules\cas-server-support-jdbc-3.5.2.jaroracle驅動(這裏採用oracle數據)的ojdbc14.jar或者classes12.jar放到cas/WEB-INF/lib目錄下。

  4. 重新登陸Web系統

    重啓tomcat,在瀏覽器中輸入https://sso.aurora-framework.org:8080/yourapp/,自動跳轉到如下頁面:

  5. 輸入web系統預先定義的用戶名和密碼,並跳轉到自定義(web.xml中定義的)登陸成功後的頁面。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章