1. 程式人生 > >spring security+cas(cas proxy配置)

spring security+cas(cas proxy配置)

interface iteye RF lns key sock nag spec uitable

什麽時候會用到代理proxy模式?

舉一個例子:有兩個應用App1和App2,它們都是受Cas服務器保護的,即請求它們時都需要通過Cas 服務器的認證。現在需要在App1中通過Http請求訪問App2,顯然該請求將會被App2配置的Cas的AuthenticationFilter攔截並轉向Cas 服務器,Cas 服務器將引導用戶進行登錄認證,這樣我們也就訪問不到App2的資源了。針對這種應用場景,Cas也提供了Cas Proxy 輕松的解決了這個問題。

cas server 版本4.1.3

cas clietn版本4.0.0

cas搭建參考:http://www.cnblogs.com/l412382979/p/8818765.html

cas proxy配置參考地址:http://elim.iteye.com/blog/2270446

cas server配置deployerConfigContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--

    Licensed to Apereo under one or more contributor license
    agreements. See the NOTICE file distributed with this work
    for additional information regarding copyright ownership.
    Apereo licenses this file to you under the Apache License,
    Version 2.0 (the "License"); you may not use this file
    except in compliance with the License.  You may obtain a
    copy of the License at the following location:

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->
<!--
| deployerConfigContext.xml centralizes into one file some of the declarative configuration that
| all CAS deployers will need to modify.
|
| This file declares some of the Spring-managed JavaBeans that make up a CAS deployment.
| The beans declared in this file are instantiated at context initialization time by the Spring
| ContextLoaderListener declared in web.xml.  It finds this file because this
| file is among those declared in the context parameter "contextConfigLocation".
|
| By far the most common change you will need to make in this file is to change the last bean
| declaration to replace the default authentication handler with
| one implementing your approach for authenticating usernames and passwords.
+-->

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:sec="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!--
       | The authentication manager defines security policy for authentication by specifying at a minimum
       | the authentication handlers that will be used to authenticate credential. While the AuthenticationManager
       | interface supports plugging in another implementation, the default PolicyBasedAuthenticationManager should
       | be sufficient in most cases.
       +-->
    <bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
        <constructor-arg>
            <map>
                <!--
                   | IMPORTANT
                   | Every handler requires a unique name.
                   | If more than one instance of the same handler class is configured, you must explicitly
                   | set its name to something other than its default name (typically the simple class name).
                   -->
                <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
                <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />
                 <!-- key-ref指定自己的本地數據庫訪問 -->
				<entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver"/>
            </map>
        </constructor-arg>

        <!-- Uncomment the metadata populator to capture the password.
        <property name="authenticationMetaDataPopulators">
           <util:list>
               <bean class="org.jasig.cas.authentication.CacheCredentialsMetaDataPopulator"/>
           </util:list>
        </property>
        -->

        <!--
           | Defines the security policy around authentication. Some alternative policies that ship with CAS:
           |
           | * NotPreventedAuthenticationPolicy - all credential must either pass or fail authentication
           | * AllAuthenticationPolicy - all presented credential must be authenticated successfully
           | * RequiredHandlerAuthenticationPolicy - specifies a handler that must authenticate its credential to pass
           -->
        <property name="authenticationPolicy">
            <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />
        </property>
    </bean>

    <!-- Required for proxy ticket mechanism. -->
    <bean id="proxyAuthenticationHandler"
          class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
          p:httpClient-ref="supportsTrustStoreSslSocketFactoryHttpClient" p:requireSecure="false"/>

    <!--
       | TODO: Replace this component with one suitable for your enviroment.
       |
       | This component provides authentication for the kind of credential used in your environment. In most cases
       | credential is a username/password pair that lives in a system of record like an LDAP directory.
       | The most common authentication handler beans:
       |
       | * org.jasig.cas.authentication.LdapAuthenticationHandler
       | * org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler
       | * org.jasig.cas.adaptors.x509.authentication.handler.support.X509CredentialsAuthenticationHandler
       | * org.jasig.cas.support.spnego.authentication.handler.support.JCIFSSpnegoAuthenticationHandler
       -->
    <bean id="primaryAuthenticationHandler"
          class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler">
        <property name="users">
            <map>
                <entry key="casuser" value="Mellon"/>
            </map>
        </property>
    </bean>

    <!-- Required for proxy ticket mechanism -->
    <bean id="proxyPrincipalResolver"
          class="org.jasig.cas.authentication.principal.BasicPrincipalResolver" />

    <!--
       | Resolves a principal from a credential using an attribute repository that is configured to resolve
       | against a deployer-specific store (e.g. LDAP).
       -->
    <bean id="primaryPrincipalResolver"
          class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver"
          p:principalFactory-ref="principalFactory"
          p:attributeRepository-ref="attributeRepository" />

    <!--
    Bean that defines the attributes that a service may return.  This example uses the Stub/Mock version.  A real implementation
    may go against a database or LDAP server.  The id should remain "attributeRepository" though.
    +-->

    <bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> 
	    <constructor-arg index="0" ref="dataSource" /> 
	    <constructor-arg index="1" value="select ID_ as id,PASSWORD_ as pwd from USER_TABLE where {0}" /> 
	    <property name="queryAttributeMapping"> 
	       <map> 
	           <!-- 這裏的key需寫username和登錄頁面一致,value對應數據庫用戶名字段 
	           		select ID_ as id from USER_TABLE where USERNAME_=#username#
	            -->
	           <entry key="username" value="USERNAME_"/> 
	       </map> 
	    </property> 
	    <property name="resultAttributeMapping"> 
	       <map> 
	          <!--  key為對應的數據庫字段名稱,value為提供給客戶端獲取的屬性名字,系統會自動填充值  -->
	           <entry key="id" value="id"/> 
	           <entry key="pwd" value="pwd"/> 
	       </map> 
	    </property> 
    </bean>


     <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl" 
      p:registeredServices-ref="registeredServicesList" />
      
      <util:list id="registeredServicesList">
	    <bean class="org.jasig.cas.services.RegexRegisteredService"
	          p:id="1"
	          p:name="HTTPS and IMAPS services on example.com"
	          p:serviceId="^(https?|imaps?|http?)://.*"
	          p:evaluationOrder="0" >
	          <!-- 基於正則表達式匹配代理端,以下這行不加的話代理端會被cas server拒絕 -->
	            <property name="proxyPolicy">
	        		<bean class="org.jasig.cas.services.RegexMatchingRegisteredServiceProxyPolicy" c:pgtUrlPattern="^https?://.*" />
	            </property>
	   </bean>
	</util:list>

    <bean id="auditTrailManager" class="org.jasig.inspektr.audit.support.Slf4jLoggingAuditTrailManager" />

    <bean id="healthCheckMonitor" class="org.jasig.cas.monitor.HealthCheckMonitor" p:monitors-ref="monitorsList" />

    <util:list id="monitorsList">
        <bean class="org.jasig.cas.monitor.MemoryMonitor" p:freeMemoryWarnThreshold="10" />
        <!--
          NOTE
          The following ticket registries support SessionMonitor:
            * DefaultTicketRegistry
            * JpaTicketRegistry
          Remove this monitor if you use an unsupported registry.
        -->
        <bean class="org.jasig.cas.monitor.SessionMonitor"
              p:ticketRegistry-ref="ticketRegistry"
              p:serviceTicketCountWarnThreshold="5000"
              p:sessionCountWarnThreshold="100000" />
    </util:list>
    
    <!-- 訪問本地數據庫 -->
	<bean id="dbAuthHandler"
	      class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
	      <property name="dataSource" ref="dataSource"></property>  
	      <property name="sql" value="SELECT PASSWORD_ FROM USER_TABLE WHERE USERNAME_ = ? and ISACTIVE_=‘Y‘ "></property> 
		  <property name="passwordEncoder" ref="MD5PasswordEncoder"></property>
	</bean>	  
	  
	<!-- SSO密碼加密配置 -->  
    <bean id="MD5PasswordEncoder" class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder">  
        <constructor-arg index="0">  
            <value>MD5</value>  
        </constructor-arg>  
    </bean> 
    
    <!-- mysql連接 -->
	<!--  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
	    <property name="url" value="jdbc:mysql://localhost:3306/cas?useUnicode=true&characterEncoding=UTF-8"/>
	    <property name="username" value="root" />
	    <property name="password" value="root" />
	</bean> -->
	
	<!-- oracle連接 -->
	 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
		<property name="username" value="username" />
		<property name="password" value="password" />
	</bean>
</beans>

  代理端應用配置(app1)註意:文件中${casClientRoot}和${cas.server.url}在properties文件中配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:s="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.1.xsd">

	<!-- <s:http pattern="/saveMyCss.json" security="none" />  -->
	<!-- sso -->
	<s:http auto-config="true" entry-point-ref="casAuthenticationEntryPoint"  servlet-api-provision="true">
		<s:intercept-url pattern="/login.jsp" access="ROLE_USER"></s:intercept-url>
		<s:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" />  
		<s:custom-filter ref="singleLogoutFilter" before="CAS_FILTER" /> 
		<!-- 增加一個filter,這點與Acegi是不一樣的,不能修改默認的filter了,這個filter位於FILTER_SECURITY_INTERCEPTOR之前-->
		<s:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>
		<s:custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />
	</s:http>
	
	<s:authentication-manager alias="authenticationManager">
		<s:authentication-provider ref="casAuthenticationProvider"></s:authentication-provider>
	</s:authentication-manager>
	
	<!-- http://localhost:8088/SpringSecurity 具體應用 -->
	<!-- j_spring_cas_security_check spring的虛擬URL,此標誌標識使用 CAS authentication upon return from CAS SSO login. -->
	<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
		<property name="service" value="${casClientRoot}j_spring_cas_security_check"></property>
		<property name="sendRenew" value="false"></property>
	</bean>
	
	<!-- 配置ProxyGrantingTicketStorage,用以保存pgtId和pgtIou -->
	<bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl"/>
	
	<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
		<property name="authenticationManager" ref="authenticationManager" />
		<property name="authenticationSuccessHandler" ref="loginSuccess" />
		<property name="authenticationFailureHandler" ref="loginFail" />
		<!-- 指定處理地址,不指定時默認將會是“/j_spring_cas_security_check” -->
		<property name="filterProcessesUrl" value="/j_spring_cas_security_check" />
		<!-- 保存cas server傳遞過來的pgtId和pgtIou -->
		<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage"/>
		<!-- 用以指定Cas Server在回調代理端傳遞pgtId和pgtIou時回調地址相對於代理端的路徑 -->
		<property name="proxyReceptorUrl" value="/proxyCallback"/>
	</bean>
	
	<!-- loginUrl cas 服務登錄地址 -->
	<bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
		<property name="loginUrl" value="${cas.server.url}login" /> 
		<property name="serviceProperties" ref="serviceProperties" />
	</bean>
	
	<!-- ticketValidator cas服務驗證地址 -->
	<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
		<property name="userDetailsService" ref="userDetailServiceImpl" />
		<property name="serviceProperties" ref="serviceProperties" />
		<!-- 配置TicketValidator在登錄認證成功後驗證ticket -->
		<property name="ticketValidator">
			<bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">
				<!-- Cas Server訪問地址的前綴,即根路徑-->
				<!-- cas.server.url https://localhost:8888/cas-server/ -->
				<constructor-arg index="0" value="${cas.server.url}" />
				<!-- 指定Cas Server回調傳遞pgtId和pgtIou的地址,該地址必須使用https協議 -->
				<!-- casClientRoot https://localhost:8080/app1/ -->
				<property name="proxyCallbackUrl" value="${casClientRoot}proxyCallback"/>
				<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage"/>
			</bean>
		</property>
		<property name="key" value="key4CasAuthenticationProvider" />
	</bean>
	
	<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"></bean>
	
	<!-- 一個自定義的filter,必須包含authenticationManager,accessDecisionManager,securityMetadataSource三個屬性,
		我們的所有控制將在這三個類中實現,解釋詳見具體配置 -->
	<bean id="filterSecurityInterceptor"
		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
		<property name="authenticationManager" ref="authenticationManager" />
		<property name="accessDecisionManager" ref="dbAccessDecisionManagerBean" />
		<property name="securityMetadataSource" ref="securityMetadataSource" />
	</bean>
	
	<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
	
	<bean id="userDetailServiceImpl" class="com.common.security.UserDetailsServiceImpl">
		<property name="dao" ref="dao" />
	</bean>
	
	<!-- 訪問決策器,決定某個用戶具有的角色,是否有足夠的權限去訪問某個資源 -->
	<bean id="dbAccessDecisionManagerBean" class="com.common.security.DbAccessDecisionManager">
	</bean>

	<!-- 資源源數據定義,即定義某一資源可以被哪些角色訪問 -->
	<bean id="securityMetadataSource" class="com.common.security.DbInvocationSecurityMetadataSource">
		<property name="securityData" ref="securityData" />
	</bean>

	<bean id="securityData" class="com.common.security.SecurityData">
		<property name="dao" ref="dao" />
	</bean>
	<!-- 用戶需要登錄時跳轉的地址 -->
	<bean id="authenticationEntryPoint" class="com.common.security.AuthenticationEntryPoint">
		<property name="loginFormUrl" value="/loginre.jsp" />
	</bean>
	
	<!-- 用戶登錄失敗 -->
	<bean id="loginFail" class="com.common.security.LoginFail">
		<property name="url" value="login.jsp" />
	</bean>

	<!-- 用戶登錄成功 -->
	<bean id="loginSuccess" class="com.common.security.loginSuccess">
		<property name="url" value="ire.htm" />
	</bean>
	
	 <!-- 註銷客戶端 --> 
    <bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter" /> 
	
	<!-- 註銷服務器端 --> 
    <bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> 
	    <constructor-arg  value="${cas.server.url}logout?service=${casClientRoot}" /> 
	    <constructor-arg> 
	    	<bean  class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> 
	    </constructor-arg> 
	    <property name="filterProcessesUrl" value="/j_spring_cas_security_logout" /> 
    </bean> 

</beans>

  被代理端配置(app2)註意:文件中${casClientRoot}和${cas.server.url}在properties文件中配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:s="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.1.xsd">

	<!-- <s:http pattern="/saveMyCss.json" security="none" />  -->
	<!-- sso -->
	<s:http auto-config="true" entry-point-ref="casAuthenticationEntryPoint"  servlet-api-provision="true">
		<s:intercept-url pattern="/login.jsp" access="ROLE_USER"></s:intercept-url>
		<s:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" />  
		<s:custom-filter ref="singleLogoutFilter" before="CAS_FILTER" /> 
		<!-- 增加一個filter,這點與Acegi是不一樣的,不能修改默認的filter了,這個filter位於FILTER_SECURITY_INTERCEPTOR之前-->
		<s:custom-filter ref="filterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>
		<s:custom-filter ref="casAuthenticationFilter" position="CAS_FILTER" />
	</s:http>
	
	<s:authentication-manager alias="authenticationManager">
		<s:authentication-provider ref="casAuthenticationProvider"></s:authentication-provider>
	</s:authentication-manager>
	
	<!-- http://localhost:8088/SpringSecurity 具體應用 -->
	<!-- j_spring_cas_security_check spring的虛擬URL,此標誌標識使用 CAS authentication upon return from CAS SSO login. -->
	<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties">
		<!-- casClientRoot https://localhost:8080/app2/ -->
		<property name="service" value="${casClientRoot}j_spring_cas_security_check"></property>
		<!-- <property name="sendRenew" value="false" /> -->
		<!-- 通過ServiceProperties指定CasAuthenticationFilter的authenticateAllArtifacts為true -->
		<property name="authenticateAllArtifacts" value="true"/>
	</bean>
	
	<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter">
		<property name="authenticationManager" ref="authenticationManager" />
		<property name="authenticationSuccessHandler" ref="loginSuccess" />
		<property name="authenticationFailureHandler" ref="loginFail" />
		<!-- 指定處理地址,不指定時默認將會是“/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">
			<bean class="org.springframework.security.cas.web.authentication.ServiceAuthenticationDetailsSource" />
		</property>
	</bean>
	
	<!-- loginUrl cas 服務登錄地址 -->
	<bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
		<property name="loginUrl" value="${cas.server.url}login" /> 
		<property name="serviceProperties" ref="serviceProperties" />
	</bean>
	
	<!-- ticketValidator cas服務驗證地址 -->
	<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
		<property name="userDetailsService" ref="userDetailServiceImpl" />
		<property name="serviceProperties" ref="serviceProperties" />
		<!-- 配置TicketValidator在登錄認證成功後驗證ticket -->
		<property name="ticketValidator">
			<bean class="org.jasig.cas.client.validation.Cas20ProxyTicketValidator">
				<!-- Cas Server訪問地址的前綴,即根路徑-->
				<!-- cas.server.url https://localhost:8888/cas-server/ -->
				<constructor-arg index="0" value="${cas.server.url}" />
				<!-- 如果有多個代理端可以多寫幾個value -->
				<property name="allowedProxyChains">
					<value>https://localhost:8080/app1/proxyCallback</value>
				</property>
			</bean>
		</property>
		<property name="key" value="key4CasAuthenticationProvider" />
		<property name="statelessTicketCache">
			<bean class="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>
	
	<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"></bean>
	
	<!-- 一個自定義的filter,必須包含authenticationManager,accessDecisionManager,securityMetadataSource三個屬性,
		我們的所有控制將在這三個類中實現,解釋詳見具體配置 -->
	<bean id="filterSecurityInterceptor"
		class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
		<property name="authenticationManager"
			ref="authenticationManager" />
		<property name="accessDecisionManager"
			ref="dbAccessDecisionManagerBean" />
		<property name="securityMetadataSource"
			ref="securityMetadataSource" />
	</bean>
	
	<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
	
	<bean id="userDetailServiceImpl" class="com.common.security.UserDetailsServiceImpl">
		<property name="dao" ref="dao" />
	</bean>
	
	<!-- 訪問決策器,決定某個用戶具有的角色,是否有足夠的權限去訪問某個資源 -->
	<bean id="dbAccessDecisionManagerBean" class="com.common.security.DbAccessDecisionManager">
	</bean>

	<!-- 資源源數據定義,即定義某一資源可以被哪些角色訪問 -->
	<bean id="securityMetadataSource" class="com.common.security.DbInvocationSecurityMetadataSource">
		<property name="securityData" ref="securityData" />
	</bean>

	<bean id="securityData" class="com.common.security.SecurityData">
		<property name="dao" ref="dao" />
	</bean>
	<!-- 用戶需要登錄時跳轉的地址 -->
	<bean id="authenticationEntryPoint" class="com.common.security.AuthenticationEntryPoint">
		<property name="loginFormUrl" value="/loginre.jsp" />
	</bean>
	
	<!-- 用戶登錄失敗 -->
	<bean id="loginFail" class="com.common.security.LoginFail">
		<property name="url" value="login.jsp" />
	</bean>

	<!-- 用戶登錄成功 -->
	<bean id="loginSuccess" class="com.common.security.loginSuccess">
		<property name="url" value="ire.htm" />
	</bean>
	
	 <!-- 註銷客戶端 --> 
    <bean id="singleLogoutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter" /> 
	
	<!-- 註銷服務器端 --> 
    <bean id="requestSingleLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> 
	    <constructor-arg  value="${cas.server.url}logout?service=${casClientRoot}" /> 
	    <constructor-arg> 
	    	<bean  class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> 
	    </constructor-arg> 
	    <property name="filterProcessesUrl" value="/j_spring_cas_security_logout" /> 
    </bean> 

</beans>

  代理端請求被代理端的請求

 CasAuthenticationToken cat = (CasAuthenticationToken)SecurityContextHolder.getContext().getAuthentication();
        AttributePrincipal principal = cat.getAssertion().getPrincipal();
        String proxyTicket = principal.getProxyTicketFor("https://localhost:8080/app2/testPost.json");
        String url = "https://localhost:8080/app2/testPost.json?ticket=" + URLEncoder.encode(proxyTicket, "UTF-8");
        HttpsURLConnection conn =null;
        StringBuilder sb = new StringBuilder();
        try {
            URL assessUrl = new URL(url);
            conn  = (HttpsURLConnection)assessUrl.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(),
                "UTF-8"));
            String param = "xmlPath=scott";
            writer.write(param);
            writer.flush();
            writer.close();
            InputStreamReader reader = new InputStreamReader(conn.getInputStream());
            int read = -1;
            char[] buffer = new char[4096];
            while ((read = reader.read(buffer)) != -1) {
                sb.append(buffer, 0, read);
            }
            reader.close();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }

  被代理端的接口

    @RequestMapping(value = "/testPost.json")
    public void synUser( String xmlPath) throws Exception {
        System.out.println(xmlPath);
    }

  

spring security+cas(cas proxy配置)