spring security 3整合cas client用於實現各Application之間的單點登錄。
1. 需要准備的jar
spring-security-core-3.0.8.RELEASE.jar spring-security-web-3.0.8.RELEASE.jar spring-security-config-3.0.8.RELEASE.jar spring-security-cas-client-3.0.8.RELEASE.jar cas-client-core-3.2.1.jar (jasig)
2. web.xml
web.xml中加入context param 和 filter
<!--context configuration--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springSecurity.xml</param-value> </context-param> <!-- Spring security filter --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3. spring security cas-client配置
springSecurity.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:security="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <!-- cas攔截規則 --> <security:http auto-config="true" entry-point-ref="casAuthEntryPoint" servlet-api-provision="true"> <security:intercept-url pattern="/login.do" access="ROLE_USER,ROLE_ADMIN"/> <security:intercept-url pattern="/report/*.do" access="ROLE_USER,ROLE_ADMIN"/> <security:intercept-url pattern="/packages/*add.do" access="ROLE_USER,ROLE_ADMIN"/> <security:intercept-url pattern="/packages/*delete.do" access="ROLE_USER,ROLE_ADMIN"/> <security:intercept-url pattern="/packages/*edit.do" access="ROLE_USER,ROLE_ADMIN"/> <security:intercept-url pattern="/resource/*.do" access="ROLE_USER,ROLE_ADMIN"/> <security:intercept-url pattern="/equip/*.do" access="ROLE_ADMIN"/> <security:custom-filter ref="casAuthenticationFilter" position="CAS_FILTER"/> <security:custom-filter ref="requestSingleLogoutFilter" before="LOGOUT_FILTER" /> <security:custom-filter ref="singleLogoutFilter" before="CAS_FILTER" /> </security:http> <!-- CAS認證切入點,聲明cas服務器端登錄的地址 --> <bean id="casAuthEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<!-- 此處loginUrl必須和瀏覽器中訪問的地址一致 --> <property name="loginUrl" value="http://10.10.144.51:8081/cas"/> <property name="serviceProperties" ref="casService"/> </bean> <!-- 在認證管理器中注冊cas認證提供器 --> <security:authentication-manager alias="authenticationManager"> <security:authentication-provider ref="casAuthenticationProvider" /> </security:authentication-manager> <!-- 登錄成功后的返回地址 --> <bean id="casService" class="org.springframework.security.cas.ServiceProperties"> <property name="service" value="http://10.10.144.130:8080/provisioningApp/j_spring_cas_security_check"/> <property name="sendRenew" value="false" /> </bean> <!-- cas 認證過濾器 --> <bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="authenticationFailureHandler" ref="authenticationFailureHandler" /> <property name="authenticationSuccessHandler" ref="authenticationSuccessHandler" /> <property name="filterProcessesUrl" value="/j_spring_cas_security_check" /> </bean> <!-- cas 認證失敗控制器 --> <bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/error.jsp" /> </bean> <!-- cas 認證成功控制器 --> <bean id="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler"> <property name="alwaysUseDefaultTargetUrl" value="true" /> <property name="defaultTargetUrl" value="/sim/init.do" /> </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="http://10.10.144.51:8081/cas/logout" /> <constructor-arg> <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" /> </constructor-arg> <property name="filterProcessesUrl" value="/j_spring_cas_security_logout" /> </bean> <!-- cas認證提供器,定義客戶端的驗證方式 --> <bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> <property name="ticketValidator" ref="casTicketValidator"></property> <property name="serviceProperties" ref="casService"></property> <property name="key" value="an_id_for_this_auth_provider_only"></property> <property name="authenticationUserDetailsService" ref="authenticationUserDetailsService"></property> </bean> <!-- 配置ticket validator --> <bean id="casTicketValidator" class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <constructor-arg value="http://10.10.144.51:8081/cas/"/> </bean> <bean id="authenticationUserDetailsService" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper"> <property name="userDetailsService" ref="jdbcUserService"/> </bean>
<!-- 這里沒有實現custom service就直接采用security自帶的jdbcdao實現來進行數據庫操作,這里我們重寫了sql --> <bean id="jdbcUserService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl"> <property name="dataSource" ref="dataSource"/> <property name="enableGroups" value="true"/> <property name="enableAuthorities" value="false"/>
<!-- sql查詢字段的個數必須與源碼中的字段數對應起來,否則會報錯 --> <property name="usersByUsernameQuery"> <value> select username, password,1 from user where username = ? </value> </property> <property name="groupAuthoritiesByUsernameQuery"> <value> select username, department, authority from user where username = ? </value> </property> </bean>
<!-- 定義數據源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://10.10.144.51:3306/prvn"></property> <property name="minPoolSize" value="1"></property> <property name="maxPoolSize" value="25"></property> <property name="initialPoolSize" value="3"></property> <property name="acquireIncrement" value="1"></property> <property name="maxIdleTime" value="600"></property> <property name="idleConnectionTestPeriod" value="0"></property> <property name="acquireRetryAttempts" value="30"></property> <property name="acquireRetryDelay" value="1000"></property> <property name="breakAfterAcquireFailure" value="true"></property> <property name="checkoutTimeout" value="0"></property> <property name="testConnectionOnCheckout" value="false"></property> <property name="properties"> <props> <prop key="user">pvnUser</prop> <prop key="password">123456</prop> </props> </property> </bean> </beans>