CAS Spring Security 3 整合配置

 通常来讲, Web 应用的安全性包括用户认证( Authentication )和用户受权( Authorization )两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户可否访问该系统。用户受权指的是验证某个用户是否有权限执行某个操做。在一个系统中,不一样用户所具备的权限是不一样的。好比对一个文件来讲,有的用户只能进行读取,而有的用户能够进行修改。通常来讲,系统会为不一样的用户分配不一样的角色,而每一个角色则对应一系列的权限。java

  对于上面提到的两种应用情景, Spring Security 框架都有很好的支持。在用户认证方面, Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、 HTTP 表单验证、 HTTP 摘要认证、 OpenID  LDAP 等。在用户受权方面, Spring Security 提供了基于角色的访问控制和访问控制列表( Access Control List  ACL ),能够对应用中的领域对象进行细粒度的控制。mysql

 Spring Security 整合 CAS 单点登陆  使用 CAS 进行认证和获取受权信息  使用 Spring Security 验证权限 ,则能够很好的把公共的认证和受权与具体应用剥离开来,同时简化应用的配置。本文就 Spring Security  CAS 的整合进行说明。web

一 、基本需求 
1. jdk 5.0 
2. tomcat 6 
3. Spring 3.0.5.RELEASE 
4. Spring Security 3.1.0.RELEASE 
5. CAS cas-server-3.4.7, cas-client-3.2.0 
6. 使用http协议进行传输 
7. 经过jdbc进行用户验证,须要经过casserver提供除登陆用户名之外的附加信息(用于Spring Security 进行验证权限) 
2、搭建CAS Server 
1. 把从 http://www.jasig.org/cas/download 上下载cas解压找到 cas-server-3.4.7-releasecas-server-3.4.7modulescas-server-webapp-3.4.7.war , 解压cas-server-webapp-3.4.7.war ,部署在至tomcat上端口为 8080的server上,如部署路径为 http://localhost:8080/cas 。为了达到需求目的,咱们主要须要对 /WEB-INF/deployerConfigContext.xml 文件进行修改。
spring

2. 使用 jdbc 数据源进行用户认证,须要修改 deployerConfigContext.xml  authenticationHandlers 方式 
<property name=" 
authenticationHandlers "> 
<list> 
<!-- 
| This is the authentication handler that authenticates services by means of callback via SSL, thereby validating 
| a server side SSL certificate. 
+--> 
<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" 
p:httpClient-ref="httpClient" /> 
<!-- 
| This is the authentication handler declaration that every CAS deployer will need to change before deploying CAS  
| into production. The default SimpleTestUsernamePasswordAuthenticationHandler authenticates UsernamePasswordCredentials 
| where the username equals the password. You will need to replace this with an AuthenticationHandler that implements your 
| local authentication strategy. You might accomplish this by coding a new such handler and declaring 
| edu.someschool.its.cas.MySpecialHandler here, or you might use one of the handlers provided in the adaptors modules. 
+--> 
// 
注释掉,不然只要用户名和密码一致的话均可以获得认证   
<!-- bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" / --> 

// 
数据库认证方式 
<!--DATABASE -- > 
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
<property name="dataSource" ref="dataSource" /> 
<property name="sql" value="select password from t_admin_user where login_name=?" /> 
</bean> 

</list> 
<property name="authenticationHandlers">
sql

<!-- DATABASE 增长数据源配置 --> 
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property> 
<property name="url"><value>jdbc:mysql:///cas?useUnicode=true&amp;characterEncoding=utf-8</value></property> 
<property name="username"><value>root</value></property> 
</bean>
数据库

3. 经过 casserver 提供除登陆用户名之外的附加信息(用于 Spring Security 进行验证权限),修改 /WEB-INF/ deployerConfigContext .xml 
3.1 
修改 credentialsToPrincipalResolvers 
<property name="credentialsToPrincipalResolvers"> 
<list> 
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" >  
<property name="attributeRepository" ref="attributeRepository" /> // 
增长此属性,为认证过的用户的 Principal 添加属性 
</bean> 
<bean class="org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver" /> 
</list> 
</property> 

3.2 
修改该文件中默认的 attributeRepositorybean 配置 
<!-- 
使用 SingleRowJdbcPersonAttributeDao 获取更多用户的信息 --> 
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao"> 
<constructor-arg index="0" ref="dataSource"/> 
<constructor-arg index="1" value="select role_name,group_name from role where login_name = ?"/>  
<!-- 
这里的 key 需写 username,value 对应数据库用户名字段 --> 
<property name="queryAttributeMapping"> 
<map> 
<entry key="username" value="login_name"/> 
</map> 
</property> 
<!--key 
对应数据库字段, value 对应客户端获取参数 --> 
<property name="resultAttributeMapping"> 
<map> 
<entry key="role_name" value="authorities"/> // 
这个从数据库中获取的角色,用于在应用中 security 的权限验证 
</map> 
</property> 
</bean>
tomcat

3.3 修改该文件中最默认的 serviceRegistryDao 中的属性所有注释掉 
这个 bean 中的 RegisteredServiceImpl  ignoreAttributes 属性将决定是否添加 attributes 属性内容,默认为 false: 不添加,只有去掉这个配置, cas server 才会将获取的用户的附加属性添加到认证用的 Principal  attributes 中去。 
<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"></bean>
安全

3.4 若采用 CAS  Cas20ServiceTicketValidator 认证,则须要修改 WEB-INFviewjspprotocol2.0casServiceValidationSuccess.jsp 文件,才能把获取的属性传递至客户端 
<%@ page session="false" %> 
<%@ taglib prefix="c" uri=" 
http://java.sun.com/jsp/jstl/core " %> 
<%@ taglib uri=" 
http://java.sun.com/jsp/jstl/functions " prefix="fn" %> 
<cas:serviceResponse xmlns:cas=\'http://www.yale.edu/tp/cas\'> 
<cas:authenticationSuccess> 
<cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user> 

<c:if test="${not empty pgtIou}"> 
<cas:proxyGrantingTicket>${pgtIou}</cas:proxyGrantingTicket> 
</c:if> 
<c:if test="${fn:length(assertion.chainedAuthentications) > 1}"> 
<cas:proxies> 
<c:forEach var="proxy" items="${assertion.chainedAuthentications}" varStatus="loopStatus" begin="0" end="${fn:length(assertion.chainedAuthentications)-2}" step="1"> 
<cas:proxy>${fn:escapeXml(proxy.principal.id)}</cas:proxy> 
</c:forEach> 
</cas:proxies> 
</c:if> 
<!-- 
增长以下内容 --> 
<c:if test="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)> 0}"> 
<cas:attributes> 
<c:forEach  
var="attr" 
items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}" 
varStatus="loopStatus"  
begin="0" 
end="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)-1}" 
step="1"> 
<cas:${fn:escapeXml(attr.key)}>${fn:escapeXml(attr.value)}</cas:${fn:escapeXml(attr.key)}> 
</c:forEach> 
</cas:attributes> 
</c:if> 
</cas:authenticationSuccess> 
</cas:serviceResponse>
session

至此, CAS Server 搭建完毕。app

3、搭建 CAS Client (即 Spring Security )应用

1. CAS Client 下须要把 spring-security-cas-3.1.0.M2.jar  Spring Security 相关的jar 引入,把 cas-client-core-3.2.0.jar 引入,用于从 cas server 上获取相关认证与受权信息。

2. CAS Client 应用的 web.xml  增长以下 
<!-- spring 
配置文件 - -> 
<context-param> 
<param-name>contextConfigLocation</param-name> 
<param-value>classpath:applicationContext-security-ns.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>

<!-- spring 默认侦听器 --> 
<listener> 
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener>

3. spring security 文件的配置 applicationContext-security-ns.xml

<?xml version="1.0"?> 
<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: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.1.xsd ">

<!-- 
Enable security, let the casAuthenticationEntryPoint handle all intercepted urls. 
The CAS_FILTER needs to be in the right position within the filter chain. 
-->  
<security:http entry-point-ref="casAuthenticationEntryPoint" auto-config="true"> 
<security:intercept-url pattern="/**" access="ROLE_USER"></security:intercept-url> 
<security:custom-filter position="CAS_FILTER" ref="casAuthenticationFilter"></security:custom-filter> 
</security:http>

<!-- 
Required for the casProcessingFilter, so define it explicitly set and 
specify an Id Even though the authenticationManager is created by 
default when namespace based config is used. 
--> 
<security:authentication-manager alias="authenticationManager"> 
<security:authentication-provider ref="casAuthenticationProvider"></security:authentication-provider> 
</security:authentication-manager>

<!-- 
This section is used to configure CAS. The service is the 
actual redirect that will be triggered after the CAS login sequence. 
--> 
<bean id="serviceProperties" class="org.springframework.security.cas.ServiceProperties"> 
//http://localhost:8088/SpringSecurity 
具体应用 
// j_spring_cas_security_check spring 
的虚拟 URL ,此标志标识使用 CAS authentication upon return from CAS SSO login. 
<property name="service" value=" 
http://localhost:8088/SpringSecurity/j_spring_cas_security_check"></property > 
<property name="sendRenew" value="false"></property> 
</bean>

<!-- 
The CAS filter handles the redirect from the CAS server and starts the ticket validation. 
--> 
<bean id="casAuthenticationFilter" class="org.springframework.security.cas.web.CasAuthenticationFilter"> 
<property name="authenticationManager" ref="authenticationManager"></property> 
</bean>

<!-- 
The entryPoint intercepts all the CAS authentication requests. 
It redirects to the CAS loginUrl for the CAS login page. 
--> 
<bean id="casAuthenticationEntryPoint" class="org.springframework.security.cas.web.CasAuthenticationEntryPoint"> 
<property name="loginUrl" value=" 
http://localhost:8080/cas/login"></property> //SSO 登陆地址 
<property name="serviceProperties" ref="serviceProperties"></property> 
</bean>

<!-- 
Handles the CAS ticket processing. 
--> 
<bean id="casAuthenticationProvider" class="org.springframework.security.cas.authentication.CasAuthenticationProvider"> 
<property name="authenticationUserDetailsService" ref="authenticationUserDetailsService"/> 
<property name="serviceProperties" ref="serviceProperties"></property> 
<property name="ticketValidator"> 
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> 
<constructor-arg index="0" value=" 
http://localhost:8080/cas " /> //SSO 验证地址 
</bean> 
</property> 
<property name="key" value="cas"></property> 

</bean> 
<!-- authorities 
对应 CAS server  登陆属性, 在此设置到 spirng security 中,用于spring security 的验证 --> 
<bean id="authenticationUserDetailsService" class="org.springframework.security.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService"> 
<constructor-arg> 
<array> 
<value>authorities</value> 
</array> 
</constructor-arg> 
</bean> 
</beans>

至此, CAS 客户端搭建完毕。

4、总结

经过上述的配置,则具体应用在使用的时候,用户认证和受权则无需过问,只需在应用中配置相关的角色访问权限便可。即,只需对下面的红色部分进行修改,便可以完成应用的认证和受权工做。大大简化了应用和认证与受权的剥离工做

<security:http entry-point-ref="casAuthenticationEntryPoint" auto-config="true"> 
<security:intercept-url pattern="/**" access="ROLE_USER"></security:intercept-url>  
<security:custom-filter position="CAS_FILTER" ref="casAuthenticationFilter"></security:custom-filter> 
</security:http>

5、扩展

若在同一 SSO 下有多个应用, 同一户在不一样应用下有不一样的角色,则考虑扩展获取用户权限的环节;资源和角色在数据库中进行配置等等。

相关文章
相关标签/搜索