1.1. https協定改成http
1.1.1. cas服務端改以下檔案支援http協定
主要改進以下配置檔案:
1) ticketGrantingTicketCookieGenerator.xml 配置檔案
<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
p:cookieSecure="false"
p:cookieMaxAge="-1"
p:rememberMeMaxAge="120960"
p:cookieName="CASTGC"
p:cookiePath="/cas" />
将p:cookieSecure="true"改為p:cookieSecure="false",這裡我們已經改過了。
2) warnCookieGenerator.xml 配置檔案
<bean id="warnCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"
p:cookieSecure="false"
p:cookieMaxAge="-1"
p:cookieName="CASPRIVACY"
p:cookiePath="/cas" />
同樣将p:cookieSecure="true"改為p:cookieSecure="false"
3) deployerConfigContext.xml 配置檔案:
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" />
将以上的檔案改為
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" p:requireSecure="false"/>
加入p:requireSecure="false"
完成以上的配置,cas伺服器就能支援http協定通路了
1.1.2. 增加ticket的有效性
ticketExpirationPolicies.xml配置檔案
<bean id="grantingTicketExpirationPolicy" class="org.jasig.cas.ticket.support.RememberMeDelegatingExpirationPolicy">
<property name="sessionExpirationPolicy">
<bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">
<constructor-arg index="0" value="7200000" />
</bean>
</property>
<property name="rememberMeExpirationPolicy">
<bean class="org.jasig.cas.ticket.support.TimeoutExpirationPolicy">
<constructor-arg index="0" value="120960000" />
</bean>
</property>
</bean>
在ticketExpirationPolicies.xml配置檔案中增加上面所述的代碼,可以使得ticket有效性增長。
1.2. 配置cas用戶端
1.2.1. 利用spring security使用cas
這裡我們已經假設會使用spring security的基本用法,是以下面沒有涉及到spring security的内容。
首先我們需要添加ServiceProperties的bean到我們的application context裡面去
<beans:bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
<beans:property name="service" value="http://172.16.3.151:8888/ms/j_spring_cas_security_check" />
<beans:property name="sendRenew" value="false" />
</beans:bean>
這裡的service 必須是一個由CasAuthenticationFilter 監控的URL。這個sendRenew預設是false,但如果你的程式特别敏感就應該設定成true。這個參數作用是,告訴CAS登入服務,一個單點登入沒有到達。否則,使用者需要重新輸入他們的使用者名和密碼,來獲得通路服務的權限。Value值為應用的完整路徑 + j_spring_cas_security_check ,當登入成功後會跳轉到value指定的應用。
下面配置的bean 就是展開CAS 認證的過程:
<beans:bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<!-- loginUrl : cas完整的登入位址 -->
<beans:property name="loginUrl" value="http://172.16.2.176:8080/cas/login" />
<beans:property name="serviceProperties" ref="serviceProperties" />
</beans:bean>
<beans:bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
<beans:property name="authenticationManager" ref="casAuthenticationManager" />
</beans:bean>
<authentication-manager alias="casAuthenticationManager">
<authentication-provider ref="casAuthenticationProvider"/>
</authentication-manager>
<!-- 登入驗證成功後獲得使用者權限資訊的途徑 -->
<beans:bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
<beans:property name="authenticationUserDetailsService" ref="authenticationUserDetailsService"/>
<beans:property name="serviceProperties" ref="serviceProperties"/>
<beans:property name="ticketValidator">
<beans:bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<!-- casServerUrlPrefix : CAS服務URL字首 -->
<beans:constructor-arg index="0" value="http://172.16.2.176:8080/cas"/>
</beans:bean>
</beans:property>
<!-- key : 用于幫助CasAuthenticationProvider辨別出先前認證的令牌 -->
<beans:property name="key" value="an_id_for_this_auth_provider_only"></beans:property>
</beans:bean>
<beans:bean id="authenticationUserDetailsService" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
<beans:property name="userDetailsService" ref="userDetailServiceImpl"/>
</beans:bean>
<context:annotation-config/>
<context:component-scan base-package="com.wtkj.pseccs.security"/>
上面的casAuthenticationFilter是我們自定義的過濾器,我們需要在代碼中配置<custom-filter position="CAS_FILTER"ref="casAuthenticationFilter" />一旦通過了CAS 的認證,CasAuthenticationProvider 使用一個UserDetailsService
執行個體來加載使用者的認證資訊,這裡我們使用的是自定義的UserDetailsService。
1.2.2. Session的管理
在配置cas的時候,出現的最大的問題就是session不起作用,原因就是我們沒有使session-management真正起作用。
在application context裡增加下面代碼:
<beans:bean id="sessionAuthenticationStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry"
ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
<beans:bean id="sessionRegistry"
class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/login.jsp" />
</beans:bean>
加入上面代碼可以確定session-management能真正起作用。
上面的sessionAuthenticationStrategy和concurrencyFilter也是我們自定義的過濾器,同樣也需要加入
<session-management
session-authentication-strategy-ref="sessionAuthenticationStrategy" />
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
通過以上的配置我們就可以實作spring security結合cas實作單點登入機制了。
下面是session管理的時序圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyYXPpBXYmADMwATM3IDM5YDOzETPlRXYE52bpRXYjlmZpR2btZSM942bpNnclZ3Pn5GcuEzN4USO4UyNFVSRCViQ5USNFVyLcJzN4gDO3QzLcNHduVWboNWY0RXYvwFZh9Gbud3bk9CX0Vmbug2YlRXLn52b05WY35Sarl2dvw1LcpDc0RHaiojIsJye.png)
1.2.3. Cas登入退出配置
注:Cas退出後邊完善
1.2.4. Maven需要增加的依賴
<dependency>
<groupId>cas</groupId>
<artifactId>casclient</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas-client</artifactId>
<version>3.0.8.RELEASE</version>
</dependency>