Spring Security 集成CAS實現單點登錄


 參考:http://elim.iteye.com/blog/2270446

 

 

眾所周知,Cas是對單點登錄的一種實現。本文假設讀者已經了解了Cas的原理及其使用,這些內容在本文將不會討論。Cas有Server端和Client端,Client端通常對應着我們自己的應用,Spring Security整合Cas指的就是在Spring Security應用中整合Cas Client,已達到使用Cas Server實現單點登錄和登出的效果。本文旨在描述如何在Spring Security應用中使用Cas的單點登錄。

       首先需要將Spring Security對Cas支持的jar包加入到應用的類路徑中。如果我們的應用使用Maven構造的,則可以在應用的pom.xml文件中加上如下依賴。

   <dependency>

      <groupId>org.springframework.security</groupId>

      <artifactId>spring-security-cas</artifactId>

      <version>${spring.security.version}</version>

   </dependency>

 

1.1     配置登錄認證

       加入了spring-security-cas-xxx.jar到Spring Security應用的classpath后,我們便可以開始配置我們的Spring Security應用使用Cas進行單點登錄了。

 

1.1.1配置AuthenticationEntryPoint

       首先需要做的是將應用的登錄認證入口改為使用CasAuthenticationEntryPoint。所以首先我們需要配置一個CasAuthenticationEntryPoint對應的bean,然后指定需要進行登錄認證時使用該AuthenticationEntryPoint。配置CasAuthenticationEntryPoint時需要指定一個ServiceProperties,該對象主要用來描述service(Cas概念)相關的屬性,主要是指定在Cas Server認證成功后將要跳轉的地址。

   <!-- 指定登錄入口為casEntryPoint -->

   <security:http  entry-point-ref="casEntryPoint">

      ...

   </security:http>

 

   <!-- 認證的入口 -->

   <bean id="casEntryPoint"

      class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">

      <!-- Cas Server的登錄地址,elim是我的計算機名 -->

      <property name="loginUrl" value="https://elim:8443/cas/login" />

      <!-- service相關的屬性 -->

      <property name="serviceProperties" ref="serviceProperties" />

   </bean>

 

   <!-- 指定service相關信息 -->

   <bean id="serviceProperties"class="org.springframework.security.cas.ServiceProperties">

      <!-- Cas Server認證成功后的跳轉地址,這里要跳轉到我們的Spring Security應用,之后會由CasAuthenticationFilter處理,默認處理地址為/j_spring_cas_security_check -->

      <property name="service"

         value="http://elim:8080/app/j_spring_cas_security_check" />

   </bean>

 

1.1.2配置CasAuthenticationFilter

       之后我們需要配置一個CasAuthenticationFilter,並將其放置在Filter鏈表中CAS_FILTER的位置,以處理Cas Server認證成功后的頁面跳轉,用以在Spring Security中進行認證。該Filter會將Cas Server傳遞過來的ticket(Cas概念)封裝成一個Authentication(對應UsernamePasswordAuthenticationToken,其中ticket作為該Authentication的password),然后傳遞給AuthenticationManager進行認證。

   <security:http entry-point-ref="casEntryPoint">

      ...

      <security:custom-filter ref="casFilter" position="CAS_FILTER"/>

      ...

   </security:http>

 

   <bean id="casFilter"

      class="org.springframework.security.cas.web.CasAuthenticationFilter">

      <property name="authenticationManager" ref="authenticationManager" />

      <!-- 指定處理地址,不指定時默認將會是“/j_spring_cas_security_check” -->

      <property name="filterProcessesUrl" value="/j_spring_cas_security_check"/>

   </bean>

 

1.1.3配置AuthenticationManager

       CasAuthenticationFilter會將封裝好的包含Cas Server傳遞過來的ticket的Authentication對象傳遞給AuthenticationManager進行認證。我們知道默認的AuthenticationManager實現類為ProviderManager,而ProviderManager中真正進行認證的是AuthenticationProvider。所以接下來我們要在AuthenticationManager中配置一個能夠處理CasAuthenticationFilter傳遞過來的Authentication對象的AuthenticationProvider實現,CasAuthenticationProvider。CasAuthenticationProvider首先會利用TicketValidator(Cas概念)對Authentication中包含的ticket信息進行認證。認證通過后將利用持有的AuthenticationUserDetailsService根據認證通過后回傳的Assertion對象中擁有的username加載用戶對應的UserDetails,即主要是加載用戶的相關權限信息GrantedAuthority。然后構造一個CasAuthenticationToken進行返回。之后的邏輯就是正常的Spring Security的邏輯了。

   <security:authentication-manager alias="authenticationManager">

      <security:authentication-provider ref="casAuthenticationProvider"/>

   </security:authentication-manager>

 

   <bean id="casAuthenticationProvider"

   class="org.springframework.security.cas.authentication.CasAuthenticationProvider">

      <!-- 通過username來加載UserDetails -->

      <property name="authenticationUserDetailsService">

         <beanclass="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">

            <!-- 真正加載UserDetails的UserDetailsService實現 -->

            <constructor-arg ref="userDetailsService" />

         </bean>

      </property>

      <property name="serviceProperties" ref="serviceProperties" />

      <!-- 配置TicketValidator在登錄認證成功后驗證ticket -->

      <property name="ticketValidator">

         <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">

            <!-- Cas Server訪問地址的前綴,即根路徑-->

            <constructor-arg index="0" value="https:// elim:8443/cas" />

         </bean>

      </property>

      <property name="key" value="key4CasAuthenticationProvider" />

   </bean>

 

   <bean id="userDetailsService"

      class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">

      <property name="dataSource" ref="dataSource" />

   </bean>

 

       經過以上三步配置以后,我們的Spring Security應用就已經跟Cas整合好了,可以在需要登錄的時候通過Cas Server進行單點登錄了。

 

1.2     單點登出

       Spring Security應用整合Cas Client配置單點登出功能實際和單獨使用Cas Client配置單點登出功能一樣,其根本都是通過配置一個SingleSignOutFilter響應Cas Server單點登出時的回調,配置一個SingleSignOutHttpSessionListener用於在Session過期時刪除SingleSignOutFilter存放的對應信息。SingleSignOutFilter需要配置在Cas 的AuthenticationFilter之前,對於Spring Security應用而言,該Filter通常是配置在Spring Security的配置文件中,而且是配置在CAS_FILTER之前。所以我們可以在Spring Security的配置文件中進行如下配置。

   <security:http entry-point-ref="casEntryPoint">

      <!-- SingleSignOutFilter放在CAS_FILTER之前 -->

      <security:custom-filter ref="casLogoutFilter" before="CAS_FILTER"/>

      <security:custom-filter ref="casFilter" position="CAS_FILTER"/>

      ...

   </security:http>

 

   <bean id="casLogoutFilter"class="org.jasig.cas.client.session.SingleSignOutFilter"/>

 

       然后跟單獨使用Cas Client一樣,在web.xml文件中配置一個SingleSignOutHttpSessionListener。

   <listener>

   <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>

   </listener>

 

       經過以上配置在訪問Cas Server的logout地址(如:https:elim:8443/cas/logout)進行登出時,Cas Server登出后將回調其中注冊的每一個Service(Cas概念,即client應用),此時在client應用中配置好的SingleSignOutFilter將處理對應Client應用的登出操作。

 

       雖然以上配置可以滿足我們在Spring Security應用中的單點登出要求,但Cas官方文檔和Spring Security官方文檔都推薦我們在Cas Client應用進行登出操作時,不是直接訪問Cas Server的logout,而是先登出本應用,然后告訴用戶其當前登出的只是本應用,再提供一個對應Cas Server的鏈接,使其可以進行真正的單點登出。對此,Spring Security官方文檔中給我們提供例子是提供兩個LogoutFilter,一個是登出當前Spring Security應用,一個是登出Cas Server的。

   <security:http entry-point-ref="casEntryPoint">

      <!-- 請求登出Cas Server的過濾器,放在Spring Security的登出過濾器之前 -->

      <security:custom-filter ref="requestCasLogoutFilter" before="LOGOUT_FILTER"/>

      <!-- SingleSignOutFilter放在CAS_FILTER之前 -->

      <security:custom-filter ref="casLogoutFilter" before="CAS_FILTER"/>

      <security:custom-filter ref="casFilter" position="CAS_FILTER"/>

      ...

   </security:http>

 

   <bean id="requestCasLogoutFilter"class="org.springframework.security.web.authentication.logout.LogoutFilter">

      <!-- 指定登出成功后需要跳轉的地址,這里指向Cas Server的登出URL,以實現單點登出 -->

      <constructor-arg value="https://elim:8443/cas/logout"/>

       <constructor-arg>

         <beanclass="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>

       </constructor-arg>

       <!-- 該Filter需要處理的地址,默認是Spring Security的默認登出地址“/j_spring_security_logout”-->

       <property name="filterProcessesUrl" value="/j_spring_cas_security_logout"/>

   </bean>

 

       此外,Spring Security推薦我們在使用Cas Server的單點登出時一起使用CharacterEncodingFilter,以避免SingleSignOutFilter在獲取參數時出現編碼問題。

 

1.3     使用代理

       關於Cas應用使用代理的基本原理、概念等內容的介紹不在本文討論范圍之內,如需了解請讀者參考其它資料,或者參考我的另一篇博文。本文旨在描述Spring Security應用在整合Cas后如何通過Cas Proxy訪問另一個受Cas包含的應用。

 

       使用Cas Proxy時有兩個主體,代理端和被代理端。而且我們知道代理端和被代理端針對Cas20ProxyReceivingTicketValidationFilter的配置是不一樣的,雖然整合Cas的Spring Security應用不再使用Cas20ProxyReceivingTicketValidationFilter了,但其底層的核心機制是一樣的。所以Cas整合Spring Security后的應用在作為代理端和被代理端時的配置也是不一樣的。接下來將分開講解Spring Security應用作為代理端和被代理端整合Cas后的配置。

 

1.3.1代理端

       首先需要為CasAuthenticationFilter多指定兩個參數,proxyReceptorUrl和proxyGrantingTicketStorage。proxyReceptorUrl用以指定Cas Server在回調代理端傳遞pgtId和pgtIou時回調地址相對於代理端的路徑,如“/proxyCallback”,CasAuthenticationFilter會根據proxyReceptorUrl來確定一個請求是否來自Cas Server針對proxy的回調。如果是則需要接收Cas Server傳遞過來的pgtId和pgtIou,並將它們保存在持有的ProxyGrantingTicketStorage中。CasAuthenticationProvider之后會從ProxyGrantingTicketStorage中獲取對應的pgtId,即proxy granting ticket,並將其保存在AttributePrincipal中,而AttributePrincipal又會保存到對應的Assertion中。

   <!-- 配置ProxyGrantingTicketStorage,用以保存pgtId和pgtIou -->

   <bean id="proxyGrantingTicketStorage"class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl"/>

  

   <bean id="casFilter"

      class="org.springframework.security.cas.web.CasAuthenticationFilter">

      <property name="authenticationManager" ref="authenticationManager" />

      <!-- 指定處理地址,不指定時默認將會是“/j_spring_cas_security_check” -->

      <property name="filterProcessesUrl" value="/j_spring_cas_security_check"/>

      <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage"/>

      <property name="proxyReceptorUrl" value="/proxyCallback"/>

   </bean>

 

       其次是需要將CasAuthenticationProvider持有的TicketValidator由Cas20ServiceTicketValidator改成Cas20ProxyTicketValidator。其需要配置一個ProxyGrantingTicketStorage用來獲取proxy granting ticket,即我們熟知的pgtId。在單獨使用Cas Proxy時,Cas20ProxyReceivingTicketValidationFilter內部默認持有一個ProxyGrantingTicketStorage實現,其使用的Cas20ProxyTicketValidator也將使用該ProxyGrantingTicketStorage。整合Spring Security之后, Spring Security不使用Cas20ProxyReceivingTicketValidationFilter,而直接由CasAuthenticationFilter獲取proxy granting ticket,由CasAuthenticationProvider對ticket進行校驗。Cas20ProxyTicketValidator內部沒默認的ProxyGrantingTicketStorage,所以在配置Cas20ProxyTicketValidator時我們需要給其指定一個ProxyGrantingTicketStorage實現。此外還需要為Cas20ProxyTicketValidator指定一個proxyCallbackUrl用以指定在Cas20ProxyTicketValidator通過Cas Server校驗service ticket成功后將回調哪個地址以傳遞pgtId和pgtIou。proxyCallbackUrl默認情況下必須使用https協議,而應用的其它請求可以用非https協議。其它的配置和Cas20ServiceTicketValidator一樣,Cas20ProxyTicketValidator的父類其實就是Cas20ServiceTicketValidator。

 

   <bean id="casAuthenticationProvider"

   class="org.springframework.security.cas.authentication.CasAuthenticationProvider">

      <!-- 通過username來加載UserDetails -->

      <property name="authenticationUserDetailsService">

         <beanclass="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">

            <!-- 真正加載UserDetails的UserDetailsService實現 -->

            <constructor-arg ref="userDetailsService" />

         </bean>

      </property>

      <property name="serviceProperties" ref="serviceProperties" />

      <!-- 配置TicketValidator在登錄認證成功后驗證ticket -->

      <property name="ticketValidator">

         <bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">

            <!-- Cas Server訪問地址的前綴,即根路徑-->

            <constructor-arg index="0" value="https://elim:8443/cas" />

            <!-- 指定Cas Server回調傳遞pgtId和pgtIou的地址,該地址必須使用https協議 -->

            <property name="proxyCallbackUrl"value="https://elim:8043/app/proxyCallback"/>

            <property name="proxyGrantingTicketStorage"ref="proxyGrantingTicketStorage"/>

         </bean>

      </property>

      <property name="key" value="key4CasAuthenticationProvider" />

   </bean>

 

       經過以上步驟后我們整合Cas后的Spring Security應用就可以作為代理端使用Cas proxy訪問其它被Cas保護的應用了,當然前提是其它被代理端能夠接受我們應用的代理,了解Cas Proxy的人應該都知道這一點,在接下來的Spring Security應用整合Cas作為被代理端中也會講到這部分內容。這里我們假設現在有一個應用app2能夠接受我們應用的代理訪問,那么在基於上述配置的應用中我們可以通過如下代碼訪問app2。

@Controller

@RequestMapping("/cas/test")

publicclass CasTestController {

 

   @RequestMapping("/getData")

   publicvoid getDataFromApp(PrintWriter writer) throws Exception {

      //1、從SecurityContextHolder獲取到當前的Authentication對象,其是一個CasAuthenticationToken

      CasAuthenticationToken cat = (CasAuthenticationToken)SecurityContextHolder.getContext().getAuthentication();

      //2、獲取到AttributePrincipal對象

      AttributePrincipal principal = cat.getAssertion().getPrincipal();

      //3、獲取對應的proxy ticket

      String proxyTicket = principal.getProxyTicketFor("http://elim:8081/app2/getData.jsp");

      //4、請求被代理應用時將獲取到的proxy ticket以參數ticket進行傳遞

      URL url = new URL("http://elim:8081/app2/getData.jsp?ticket=" + URLEncoder.encode(proxyTicket, "UTF-8"));

      HttpURLConnection conn = (HttpURLConnection)url.openConnection();

      BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

      StringBuffer content = new StringBuffer();

      String line = null;

      while ((line=br.readLine()) != null) {

         content.append(line).append("<br/>");

      }

      writer.write(content.toString());

   }

  

}

 

       需要注意的是通過AttributePrincipal的getProxyTicketFor()方法獲取proxy ticket時,每調用一次都會獲取一個全新的proxy ticket。用戶可以根據自己的需要將獲取到的proxy ticket按照指定的URL緩存起來,以避免每次都去針對同一個URL獲取一個全新的proxy ticket。此外,如果在被代理端認證時根據proxy ticket緩存了Authentication的話也需要我們在代理端保證針對同一URL傳遞過去的proxy ticket是一樣的,否則被代理端針對proxy ticket緩存Authentication的功能就沒用了。

 

1.3.2被代理端

       Spring Security應用整合Cas使用Cas Proxy作為被代理端時主要需要進行三點修改。

 

       第一點是通過ServiceProperties指定CasAuthenticationFilter的authenticateAllArtifacts為true,這樣CasAuthenticationFilter將會嘗試對所有ticket進行認證,而不是只認證來自filterProccessUrl指定地址的請求。這樣代理端在請求被代理端的資源時將proxy ticket以參數ticket進行傳遞時,CasAuthenticationFilter才會讓CasAuthenticationProvider對proxy ticket進行校驗,這樣我們的請求才有可能被CasAuthenticationProvider認證成功並請求到真正的資源。

 

       第二點是指定CasAuthenticationFilter使用的AuthenticationDetailsSource為ServiceAuthenticationDetailsSource。CasAuthenticationFilter默認使用的是WebAuthenticationDetailsSource。ServiceAuthenticationDetailsSource將構建一個ServiceAuthenticationDetails對象作為當前Authentication的details對象。ServiceAuthenticationDetailsSource構建的ServiceAuthenticationDetails對象會將當前請求的地址構建為一個serviceUrl,通過其getServiceUrl()方法可以獲取到該serviceUrl地址。之后該Authentication對象傳遞到CasAuthenticationProvider進行認證時就可以從Authentication的details中獲取到對應的serviceUrl,並在通過Cas Server對代理端以參數ticket傳遞過來的proxy ticket進行驗證時連同對應的serviceUrl一起傳遞過去。因為之前代理端申請proxy ticket時就是通過該serviceUrl進行申請的,Cas Server需要對於它們的配對來驗證對應的proxy ticket是否有效。

 

       第三點是將CasAuthenticationProvider的TicketValidator由Cas20ServiceTicketValidator改為Cas20ProxyTicketValidator,因為Cas Proxy被代理端需要調用Cas Server的proxyValidator對代理端傳遞過來的proxy ticket進行驗證。此外需要通過acceptAnyProxy或allowedProxyChains指定將接受哪些代理。acceptAnyProxy用以指定是否接受所有的代理,可選值為true或false。allowedProxyChains則用以指定具體接受哪些代理,其對應的值是代理端在獲取pgtId時提供給Cas Server的回調地址,如我們需要接受前面示例中代理端的代理,則我們的allowedProxyChains的值應該是“https://elim:8043/app/proxyCallback”。如果需要接受多個代理端的代理,則在指定allowedProxyChains時多個代理端回調地址應各占一行。

 

       針對以上三點,我們的Spring Security應用整合Cas作為Cas Proxy的被代理端時需要對我們的配置進行如下改造。

   <!-- 指定service相關信息 -->

   <bean id="serviceProperties"class="org.springframework.security.cas.ServiceProperties">

      <!-- Cas Server認證成功后的跳轉地址,這里要跳轉到我們的Spring Security應用,之后會由CasAuthenticationFilter處理,默認處理地址為/j_spring_cas_security_check -->

      <property name="service"

         value="http://elim:8083/app2/j_spring_cas_security_check" />

      <!-- 通過ServiceProperties指定CasAuthenticationFilter的authenticateAllArtifacts為true -->

      <property name="authenticateAllArtifacts" value="true"/>

   </bean>

 

   <bean id="casFilter"

      class="org.springframework.security.cas.web.CasAuthenticationFilter">

      <property name="authenticationManager" ref="authenticationManager" />

      <!-- 指定處理地址,不指定時默認將會是“/j_spring_cas_security_check” -->

      <property name="filterProcessesUrl" value="/j_spring_cas_security_check" />

      <!-- 通過ServiceProperties指定CasAuthenticationFilter的authenticateAllArtifacts為true  -->

      <property name="serviceProperties" ref="serviceProperties" />

      <!-- 指定使用的AuthenticationDetailsSource為ServiceAuthenticationDetailsSource -->

      <property name="authenticationDetailsSource">

         <beanclass="org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource"/>

      </property>

   </bean>

 

   <bean id="casAuthenticationProvider"

   class="org.springframework.security.cas.authentication.CasAuthenticationProvider">

      <!-- 通過username來加載UserDetails -->

      <property name="authenticationUserDetailsService">

         <beanclass="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">

            <!-- 真正加載UserDetails的UserDetailsService實現 -->

            <constructor-arg ref="userDetailsService" />

         </bean>

      </property>

      <property name="serviceProperties" ref="serviceProperties" />

      <!-- 配置TicketValidator在登錄認證成功后驗證ticket -->

      <property name="ticketValidator">

         <bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">

            <!-- Cas Server訪問地址的前綴,即根路徑-->

            <constructor-arg index="0" value="https://elim:8443/cas" />

            <property name="allowedProxyChains">

                <value>https://elim:8043/app/proxyCallback</value>

            </property>

         </bean>

      </property>

      <property name="key" value="key4CasAuthenticationProvider" />

   </bean>

 

       此外,對於被代理端而言,代理端在對其進行訪問時都被認為是無狀態的。對於無狀態的認證CasAuthenticationProvider將在認證成功后將對應的Authentication對象以proxy tickit為key存放到所持有的StatelessTicketCache中,然后在下次代理端訪問時將優先根據代理端傳遞過來的proxy ticket從StatelessTicketCache中獲取Authentication對象,如果存在則不再進行認證,否則將繼續進行認證。CasAuthenticationProvider默認持有的StatelessTicketCache為NullStatelessTicketCache,其所有的實現都是空的。所以默認情況下,被代理端在被代理端訪問時將每次都對代理端進行認證。如果用戶不希望在被代理端每次都對代理端的請求進行認證,則可以為被代理端的CasAuthenticationProvider指定一個StatelessTicketCache。用戶可以實現自己的StatelessTicketCache,並指定CasAuthenticationProvider使用的StatelessTicketCache為該StatelessTicketCache。不過也可以使用Spring Security為我們提供的EhCacheBasedTicketCache。EhCacheBasedTicketCache是基於Ehcache實現的一個StatelessTicketCache。以下是一個為CasAuthenticationProvider配置EhCacheBasedTicketCache的示例。

   <bean id="casAuthenticationProvider"

   class="org.springframework.security.cas.authentication.CasAuthenticationProvider">

……

      <property name="statelessTicketCache">

         <beanclass="org.springframework.security.cas.authentication.EhCacheBasedTicketCache">

            <!-- Ehcache對象 -->

            <property name="cache" ref="proxyTicketCache"/>

         </bean>

      </property>

……

   </bean>

 

   <!-- 定義一個Ehcache -->

   <bean id="proxyTicketCache"class="org.springframework.cache.ehcache.EhCacheFactoryBean">

      <property name="cacheName" value="proxyTicketCache" />

      <property name="timeToLive" value="600"/>

   </bean>

 

       需要注意的是在代理端通過AttributePrincipal的getProxyTicketFor()方法獲取到的proxy ticket每次都是不一樣的,所以在被代理端通過StatelessTicketCache根據proxy ticket緩存認證對象Authentication時只有在同一proxy ticket能夠請求多次的情況下才會有用,這也就要求我們在代理端同樣能將proxy ticket緩存起來,以在請求同一地址時能使用相同的proxy ticket。

 

1.3.3既為代理端又為被代理端

       Cas Proxy的代理端和被代理端是相互獨立的,所以一個Cas應用既可以作為代理端去訪問其它Cas應用,也可以作為被代理端被其它應用訪問。當Spring Security應用整合Cas后既想作為Cas Proxy的代理端訪問其它Cas應用,也想作為被代理端被其它Cas應用訪問時只需要將上述作為代理端的配置和作為被代理端的配置整到一起就行了。以下是一段示例代碼。

   <!-- 指定service相關信息 -->

   <bean id="serviceProperties"class="org.springframework.security.cas.ServiceProperties">

      <!-- Cas Server認證成功后的跳轉地址,這里要跳轉到我們的Spring Security應用,之后會由CasAuthenticationFilter處理,默認處理地址為/j_spring_cas_security_check -->

      <property name="service"

         value="http://elim:8080/app /j_spring_cas_security_check" />

      <property name="authenticateAllArtifacts" value="true"/>

   </bean>

 

   <!-- 配置ProxyGrantingTicketStorage,用以保存pgtId和pgtIou -->

   <bean id="proxyGrantingTicketStorage"class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl"/>

  

   <bean id="casFilter"

      class="org.springframework.security.cas.web.CasAuthenticationFilter">

      <property name="authenticationManager" ref="authenticationManager" />

      <!-- 指定處理地址,不指定時默認將會是“/j_spring_cas_security_check” -->

      <property name="filterProcessesUrl" value="/j_spring_cas_security_check"/>

      <property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage"/>

      <property name="proxyReceptorUrl" value="/proxyCallback"/>

      <!-- 通過ServiceProperties指定CasAuthenticationFilter的authenticateAllArtifacts為true  -->

      <property name="serviceProperties" ref="serviceProperties" />

      <!-- 指定使用的AuthenticationDetailsSource為ServiceAuthenticationDetailsSource -->

      <property name="authenticationDetailsSource">

         <beanclass="org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource"/>

      </property>

   </bean>

 

   <bean id="casAuthenticationProvider"

   class="org.springframework.security.cas.authentication.CasAuthenticationProvider">

      <!-- 通過username來加載UserDetails -->

      <property name="authenticationUserDetailsService">

         <beanclass="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">

            <!-- 真正加載UserDetails的UserDetailsService實現 -->

            <constructor-arg ref="userDetailsService" />

         </bean>

      </property>

      <property name="serviceProperties" ref="serviceProperties" />

      <!-- 配置TicketValidator在登錄認證成功后驗證ticket -->

      <property name="ticketValidator">

         <bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">

            <!-- Cas Server訪問地址的前綴,即根路徑-->

            <constructor-arg index="0" value="https://elim:8443/cas" />

            <!-- 指定Cas Server回調傳遞pgtId和pgtIou的地址,該地址必須使用https協議 -->

            <property name="proxyCallbackUrl"value="https://elim:8043/app/proxyCallback"/>

            <property name="proxyGrantingTicketStorage"ref="proxyGrantingTicketStorage"/>

            <!-- 作為被代理端時配置接收任何代理 -->

            <property name="acceptAnyProxy" value="true"/>

         </bean>

      </property>

      <property name="key" value="key4CasAuthenticationProvider" />

   </bean>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM