spring security+cas(cas proxy配置)

何時會用到代理proxy模式?

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

 

cas server 版本4.1.3html

cas clietn版本4.0.0java

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

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

 

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文件中配置spring

<?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文件中配置sql

<?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>

  代理端請求被代理端的請求數據庫

public static String httpURLConnectionPOST(String url) {
      //一、從SecurityContextHolder獲取到當前的Authentication對象,其是一個CasAuthenticationToken
        CasAuthenticationToken cat = (CasAuthenticationToken) SecurityContextHolder.getContext()
            .getAuthentication();
        //二、獲取到AttributePrincipal對象
        AttributePrincipal principal = cat.getAssertion().getPrincipal();
        //三、獲取對應的proxy ticket
        String proxyTicket = principal.getProxyTicketFor(url);
        try {
            //四、請求被代理應用時將獲取到的proxy ticket以參數ticket進行傳遞
            url += "?ticket=" + URLEncoder.encode(proxyTicket, "UTF-8");
            URL assessUrl = new URL(url);
            // 將url 以 open方法返回的urlConnection  鏈接強轉爲HttpURLConnection鏈接  (標識一個url所引用的遠程對象鏈接)
            HttpURLConnection connection = (HttpURLConnection) assessUrl.openConnection();// 此時cnnection只是爲一個鏈接對象,待鏈接中
            // 設置鏈接輸出流爲true,默認false (post 請求是以流的方式隱式的傳遞參數)
            connection.setDoOutput(true);
            // 設置鏈接輸入流爲true
            connection.setDoInput(true);
            // 設置請求方式爲post 
            connection.setRequestMethod("POST");
            // post請求緩存設爲false
            connection.setUseCaches(false);
            // 設置該HttpURLConnection實例是否自動執行重定向
            connection.setInstanceFollowRedirects(true);
            // 設置請求頭裏面的各個屬性 (如下爲設置內容的類型,設置爲通過urlEncoded編碼過的from參數)
            // application/x-javascript text/xml->xml數據 application/x-javascript->json對象 application/x-www-form-urlencoded->表單數據
            // ;charset=utf-8 必需要,否則妙兜那邊會出現亂碼【★★★★★】
            connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
            // 創建鏈接 (請求未開始,直到connection.getInputStream()方法調用時才發起,以上各個參數設置需在此方法以前進行)
            connection.connect();
            // 建立輸入輸出流,用於往鏈接裏面輸出攜帶的參數,(輸出內容爲?後面的內容)
            DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());
            // 輸出完成後刷新並關閉流
            dataout.flush();
            dataout.close(); // 重要且易忽略步驟 (關閉流,切記!) 

            //System.out.println(connection.getResponseCode());

            // 鏈接發起請求,處理服務器響應  (從鏈接獲取到輸入流幷包裝爲bufferedReader)
            BufferedReader bf = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            StringBuilder sb = new StringBuilder(); // 用來存儲響應數據

            // 循環讀取流,若不到結尾處
            while ((line = bf.readLine()) != null) {
                //                sb.append(bf.readLine());
                sb.append(line).append(System.getProperty("line.separator"));
            }
            bf.close(); // 重要且易忽略步驟 (關閉流,切記!) 
            connection.disconnect(); // 銷燬鏈接
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

   被代理端的接口express

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

  

public static String httpURLConnectionPOST(String url) {      //一、從SecurityContextHolder獲取到當前的Authentication對象,其是一個CasAuthenticationToken        CasAuthenticationToken cat = (CasAuthenticationToken) SecurityContextHolder.getContext()            .getAuthentication();        //二、獲取到AttributePrincipal對象        AttributePrincipal principal = cat.getAssertion().getPrincipal();        //三、獲取對應的proxy ticket        String proxyTicket = principal.getProxyTicketFor(url);        try {            //四、請求被代理應用時將獲取到的proxy ticket以參數ticket進行傳遞            url += "?ticket=" + URLEncoder.encode(proxyTicket, "UTF-8");            URL assessUrl = new URL(url);            // 將url 以 open方法返回的urlConnection  鏈接強轉爲HttpURLConnection鏈接  (標識一個url所引用的遠程對象鏈接)            HttpURLConnection connection = (HttpURLConnection) assessUrl.openConnection();// 此時cnnection只是爲一個鏈接對象,待鏈接中            // 設置鏈接輸出流爲true,默認false (post 請求是以流的方式隱式的傳遞參數)            connection.setDoOutput(true);            // 設置鏈接輸入流爲true            connection.setDoInput(true);            // 設置請求方式爲post             connection.setRequestMethod("POST");            // post請求緩存設爲false            connection.setUseCaches(false);            // 設置該HttpURLConnection實例是否自動執行重定向            connection.setInstanceFollowRedirects(true);            // 設置請求頭裏面的各個屬性 (如下爲設置內容的類型,設置爲通過urlEncoded編碼過的from參數)            // application/x-javascript text/xml->xml數據 application/x-javascript->json對象 application/x-www-form-urlencoded->表單數據            // ;charset=utf-8 必需要,否則妙兜那邊會出現亂碼【★★★★★】            connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=utf-8");            // 創建鏈接 (請求未開始,直到connection.getInputStream()方法調用時才發起,以上各個參數設置需在此方法以前進行)            connection.connect();            // 建立輸入輸出流,用於往鏈接裏面輸出攜帶的參數,(輸出內容爲?後面的內容)            DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());            // 輸出完成後刷新並關閉流            dataout.flush();            dataout.close(); // 重要且易忽略步驟 (關閉流,切記!)             //System.out.println(connection.getResponseCode());            // 鏈接發起請求,處理服務器響應  (從鏈接獲取到輸入流幷包裝爲bufferedReader)            BufferedReader bf = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));            String line;            StringBuilder sb = new StringBuilder(); // 用來存儲響應數據            // 循環讀取流,若不到結尾處            while ((line = bf.readLine()) != null) {                //                sb.append(bf.readLine());                sb.append(line).append(System.getProperty("line.separator"));            }            bf.close(); // 重要且易忽略步驟 (關閉流,切記!)             connection.disconnect(); // 銷燬鏈接            return sb.toString();        } catch (Exception e) {            e.printStackTrace();        }        return null;    }

相關文章
相關標籤/搜索