读书人

《Spring Security3》第十章(CAS)第

发布时间: 2012-10-08 19:54:56 作者: rapoo

《Spring Security3》第十章(CAS)第二部分翻译(CAS高级配置)

?

高级CAS配置


?上图描述了CAS服务器内部的认证流程,如果你要实现Spring Security与CAS的集成,你可能要修改CAS服务器的配置。所以,理解CAS认证的整体流程如何工作是很重要的。

<property name="authenticationHandlers"> <list><!-- ... --> <bean value="uid=%u" /> <property name="searchBase" value="ou=Users,dc=jbcppets,dc=com" /> <property name="contextSource" ref="contextSource" /> </bean>

?不要忘记移除SimpleTestUsernamePasswordAuthenticationHandler,或者至少将其定义移到BindLdapAuthenticationHandler后面,否则你的CAS认证不会使用LDAP而是会使用这个默认实现。

<bean id="contextSource" value="password"/> <property name="baseEnvironmentProperties"> <map> <entry> <key> <value>java.naming.security.authentication</value> </key> <value>simple</value> </entry> </map> </property></bean>

?与我们配置Spring Security连接外部的(非嵌入式的)LDAP服务器很类似,CAS需要一个用户DN作为管理用户以首先绑定到LDAP目录上。在本例中,我们使用的管理员是在第九章的JBCPPets.ldif启动练习中定义的。URL? ldap://127.0.0.1:33389包含了端口33389,是SpringSecurity嵌入式LDAP服务器默认使用的。正如我们在第九章讨论的,在产品配置中,你可能更会使用LDAPS以确保CAS LDAP请求的安全。

<property name="credentialsToPrincipalResolvers"> <list> <bean /> </property> <property name="filter" value="(uid=%u)" /> <property name="principalAttributeName" value="uid" /> <property name="searchBase" value="ou=Users,dc=jbcppets,dc=com" /> <property name="contextSource" ref="contextSource" /> <property name="attributeRepository" ref bean="attributeRepository" /> </bean>

?你会发现就像Spring Security LDAP配置,相同的行为也在CAS中存在即基于DN中的目录子树根据属性匹配搜索安全实体。

<bean id="authenticationUserDetailsService" name="code">@RequestMapping(value="/account/viewCasUserProfile.do",method=RequestMethod.GET)public void showViewCasUserProfilePage(ModelMap model) { final Authentication auth = SecurityContextHolder.getContext().getAuthentication(); model.addAttribute("auth", auth); if(auth instanceof CasAuthenticationToken) { model.addAttribute("isCasAuthentication", Boolean.TRUE); } }

<!-- Common Header and Footer Omitted --><h1>View Profile</h1><p> Some information about you, from CAS:</p><ul> <li><strong>Auth:</strong> ${auth}</li> <li><strong>Username:</strong> ${auth.principal}</li> <li><strong>Credentials:</strong> ${auth.credentials}</li> <c:if test="${isCasAuthentication}"> <li><strong>Assertion:</strong> ${auth.assertion}</li> <li><strong>Assertion Attributes:</strong> <c:forEach items="${auth.assertion.attributes}" var="attr"> ${attr.key}:${attr.value}<br /> </c:forEach></li><li><strong>Assertion Attribute Principal:</strong> ${auth.assertion.principal}</li><li><strong>Assertion Principal Attributes:</strong> <c:forEach items="${auth.assertion.principal.attributes}" var="attr"> ${attr.key}:${attr.value}<br /> </c:forEach></li></c:if></ul>

<h1>Welcome to Your Account</h1><!-- omitted --><ul> <li><a href="viewCasUserProfile.do">View CAS User Profile</a></li>

<intercept-url pattern="/home.do" access="permitAll"/><intercept-url pattern="/account/home.do" access="!anonymous"/><intercept-url pattern="/account/view*Profile.do" access="!anonymous"/><intercept-url pattern="/account/*.do" access="hasRole('ROLE_USER')"/>

?在完成这些细小的UI更新后,重启JBCP Pets应用,并试图访问这个页面。你会发现在页面提供了很多assertion包含的信息。

匹配LDAP属性到CAS属性

<bean id="attributeRepository" ref="contextSource" /> <property name="requireAllQueryAttributes" value="true" /> <property name="baseDN" value="ou=Users,dc=jbcppets,dc=com" /> <property name="queryAttributeMapping"> <map> <entry key="username" value="uid" /> </map> </property> <property name="resultAttributeMapping"> <map> <entry key="cn" value="FullName" /> <entry key="sn" value="LastName" /> <entry key="description" value="role" /> </map> </property></bean>

?这个功能可能会很令人迷惑——本质上,这个类的目的将Principal与后端的LDAP目录进行匹配(这就是queryAttributeMapping属性,将Principal的username域与LDAP查询的uid属性相匹配)。提供的baseDN属性要使用LDAP进行查询(uid=ldapguest),并且属性要从匹配的条目进行读取。匹配到Principal属性使用resultAttributeMapping属性中的键值对——我们将LDAP的cn和sn属性匹配到有意义的名字,而description属性匹配到role属性,而这个role属性就是GrantedAuthorityFromAssertionAttributesUserDetailsService要进行查找的。

<cas:authenticationSuccess> <cas:user>${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}</cas:user> <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>

<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas"> <cas:authenticationSuccess> <cas:user>ldapguest</cas:user> <cas:attributes> <cas:FullName>LDAP Guest</cas:FullName> <cas:role>ROLE_USER</cas:role> <cas:LastName>Guest</cas:LastName> </cas:attributes> </cas:authenticationSuccess></cas:serviceResponse>

?当这些修改完成并重启CAS和JBCP Pets,你应该能够用ldapguest登录并访问使用ROLE_USER保护的区域。另外,你应该看一下“View CAS Profile”页面,它展现了CAS assertion返回的属性。

<bean id="samlTicketValidator" name="code"><bean id="casAuthenticationProvider" ref="samlTicketValidator"/> <property name="serviceProperties" ref="casService"/>

?重启JBCP Pets应用就会使用SAML响应进行ticket校验了。注意的是,CAS ticket响应并没有被Spring Security进行日志记录,所以你要么对JA-SIG CAS客户端类启用日志(在log4j中对org.jasig启用日志)要么使用调试查看响应的不同。

?

?

读书人网 >编程

热点推荐