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>