CAS认证后在JSF Managed Bean中获取LDAP属性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAS认证后在JSF Managed Bean中获取LDAP属性相关的知识,希望对你有一定的参考价值。

我正在为我的应用程序使用CAS身份验证。我将用户详细信息存储在LDAP Active Directory中。我在我的Web应用程序中使用spring security和JSF。我发现很难将LDAP属性(例如国家/地区,国家/地区代码)提供给托管bean。我能够从SecurityContext检索角色,用户名和密码,但我无法从ldap获取登录用户的国家/地区详细信息。

我相信在CAS身份验证之后必须有一种方法,我可以通过CAS检索ldap属性到JSF托管bean。我尝试了以下链接,但我无法获取托管bean的详细信息。

我的CAS确实从LDAP获得了角色,但我不希望我的Web应用程序与LDAP通信。

可以配置spring security + CAS来获取ldap属性吗?

在CAS身份验证之后,有人可以帮助我获取像国家这样的ldap属性吗?

Get LDAP user attributes from CAS

我附上了我的CAS deployerConfigContext.xml

            <?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: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-3.2.xsd
                   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
                   http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
                   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">



                 <bean id="authenticationManager" class="xxx.cas.authentication.XXXOTPPolicyBasedAuthenticationManager">

                    <constructor-arg index="0">
                        <list value-type="org.jasig.cas.authentication.AuthenticationHandler" >
                            <ref local="ldapAuthenticationHandler"/>
                            <ref local="radiusAuthenticationHandler"/>
                        </list>
                    </constructor-arg> 


                    <property name="authenticationPolicy">
                        <bean class="xxx.cas.authentication.XXXAllAuthenticationPolicy" />
                    </property>
                </bean>

                <!-- Required for proxy ticket mechanism. -->
                <bean id="proxyAuthenticationHandler"
                      class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
                      p:httpClient-ref="httpClient" p:requireSecure="false" />



                   <!--
                   | Change principalIdAttribute to use another directory attribute,
                   | e.g. userPrincipalName, for the NetID
                   -->
                <bean id="ldapAuthenticationHandler"
                      class="org.jasig.cas.authentication.LdapAuthenticationHandler"
                      p:principalIdAttribute="sAMAccountName"
                      c:authenticator-ref="authenticator">
                    <property name="principalAttributeMap">
                        <map>
                            <!--
                               | This map provides a simple attribute resolution mechanism.
                               | Keys are LDAP attribute names, values are CAS attribute names.
                               | Use this facility instead of a PrincipalResolver if LDAP is
                               | the only attribute source
                               -->
                            <entry key="displayName" value="displayName" />
                            <entry key="facsimileTelephoneNumber" value="facsimileTelephoneNumber" />
                            <entry key="memberOf" value="memberOf" />
                            <entry key="co" value="co" />
                            <entry key="c" value="c" />
                            <entry key="mail" value="mail" />
                            <entry key="description" value="role" />
                        </map>
                    </property>
                </bean>



                <!-- Required for proxy ticket mechanism -->
                <bean id="proxyPrincipalResolver"
                      class="org.jasig.cas.authentication.principal.BasicPrincipalResolver" />


                <!-- Radius authentication -->
                <bean id="radiusClientFactory"
                      class="org.jasig.cas.adaptors.radius.RadiusClientFactory"
                      p:inetAddress="${fourtress.server}"
                      p:sharedSecret="${fourtress.ss}" />

                <bean id="radiusServer"
                      class="org.jasig.cas.adaptors.radius.JRadiusServerImpl"
                      c:protocol="PAP"
                      c:clientFactory-ref="radiusClientFactory" />

                <bean id="radiusAuthenticationHandler"
                      class="xxx.cas.authentication.XXXRadiusAuthenticationHandler">
                  <property name="servers">
                      <list>
                          <ref local="radiusServer" />
                      </list>
                  </property>
                </bean>




                <bean id="attributeRepository"
                  class="org.jasig.cas.persondir.LdapPersonAttributeDao"
                  p:connectionFactory-ref="pooledLdapConnectionFactory"
                  p:baseDN="ou=users,ou=egate,dc=egate-t,dc=local" p:searchControls-ref="searchControls" p:searchFilter="sAMAccountName={0}">

                    <property name="requireAllQueryAttributes" value="true"/>
                    <property name="queryAttributeMapping">
                        <map>
                            <!-- Attribute mapping between principal (key) and LDAP (value) names used to perform the LDAP search -->
                            <entry key="username" value="sAMAccountName" />
                        </map>
                    </property>
                    <property name="resultAttributeMapping">
                        <map>
                            <!-- Mapping between LDAP entry attributes (key) and Principal's (value) -->
                            <entry key="memberOf" value="memberOf" />
                            <entry key="mail" value="mail" />
                            <entry key="cn" value="FullName" />
                            <entry key="sn" value="LastName" />
                            <entry key="displayName" value="displayName" />
                            <entry key="description" value="role" />
                            <entry key="facsimileTelephoneNumber" value="facsimileTelephoneNumber" />
                            <entry key="co" value="country" />
                            <entry key="c" value="countryCode" />

                        </map>
                    </property>
                </bean>

                <bean id="searchControls"
                      class="javax.naming.directory.SearchControls"
                      p:searchScope="2"
                      p:countLimit="0" p:timeLimit="0" />


                <!--
                Sample, in-memory data store for the ServiceRegistry. A real implementation
                would probably want to replace this with the JPA-backed ServiceRegistry DAO
                The name of this bean should remain "serviceRegistryDao".
                +-->
                <bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl"
                        p:registeredServices-ref="registeredServicesList" />

                <util:list id="registeredServicesList">

                    <bean class="org.jasig.cas.services.RegexRegisteredService">
                        <property name="id" value="1" />
                        <property name="name" value="cassimple" />
                        <property name="description" value="cassimple application 1" />
                        <property name="serviceId" value="^(http?|https?|imaps?)://localhost:7002/cassimple/.*" />
                        <property name="evaluationOrder" value="10000001" />
                    </bean>

                    <bean class="org.jasig.cas.services.RegexRegisteredService">
                        <property name="id" value="2" />
                        <property name="name" value="casldap" />
                        <property name="description" value="casldap application 2" />
                        <property name="serviceId" value="^(http?|https?|imaps?)://localhost:7002/casldap/.*" />
                        <property name="evaluationOrder" value="10000002" />
                        <property name="allowedAttributes">
                            <list>
                                <value>memberOf</value>
                                <value>LastName</value>
                                <value>FullName</value>
                                <value>displayName</value>
                                <value>role</value>
                            </list>
                        </property>            
                    </bean>

                    <bean class="org.jasig.cas.services.RegexRegisteredService">
                        <property name="id" value="3" />
                        <property name="name" value="cascir" />
                        <property name="description" value="cas cir application 3" />
                        <property name="serviceId" value="^(http?|https?|imaps?)://localhost:7002/cascir/.*" />
                        <property name="evaluationOrder" value="10000003" />
                        <property name="allowedAttributes">
                            <list>
                                <value>role</value>
                                <value>FullName</value>
                                <value>displayName</value>
                                <value>LastName</value>
                                <value>memberOf</value>
                            </list>
                        </property>            
                    </bean>

                    <bean class="org.jasig.cas.services.RegexRegisteredService">
                        <property name="id" value="4" />
                        <property name="name" value="egate" />
                        <property name="description" value="cas egate application 4" />
                        <property name="serviceId" value="^(http?|https?|imaps?)://localhost:7002/egate/.*" />
                        <property name="evaluationOrder" value="10000004" />
                        <property name="allowedAttributes">
                            <list>
                                <value>role</value>
                                <value>FullName</value>
                                <value>displayName</value>
                                <value>LastName</value>
                                <value>memberOf</value>
                            </list>
                        </property>            
                    </bean>

                    <bean class="org.jasig.cas.services.RegexRegisteredService">
                        <property name="id" value="5" />
                        <property name="name" value="cir" />
                        <property name="description" value="cas cir application 5" />
                        <property name="serviceId" value="^(http?|https?|imaps?)://localhost:7002/cir/.*" />
                        <property name="evaluationOrder" value="10000005" />
                        <property name="allowedAttributes">
                            <list>
                                <value>role</value>
                                <value>FullName</value>
                                <value>displayName</value>
                                <value>LastName</value>
                                <value>memberOf</value>
                                <value>country</value>
                                <value>countryCode</value>
                            </list>
                        </property>            
                    </bean>





                </util:list>

                <bean id="auditTrailManager" class="com.github.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="authenticator" class="org.ldaptive.auth.Authenticator"
                      c:resolver-ref="dnResolver"
                      c:handler-ref="authHandler"
                      p:entryResolver-ref="entryResolver" />

                <!-- Active Directory UPN format. -->
                <bean id="dnResolver"
                      class="org.ldaptive.auth.FormatDnResolver"
                      c:format="${ldap.authn.format}" />

                <bean id="authHandler" class="org.ldaptive.auth.PooledBindAuthenticationHandler"
                      p:connectionFactory-ref="pooledLdapConnectionFactory" />

                <bean id="pooledLdapConnectionFactory" 
                      class="org.ldaptive.pool.PooledConnectionFactory"
                      p:connectionPool-ref="connectionPool" />


                <bean id="connectionPool"
                      class="org.ldaptive.pool.BlockingConnectionPool"
                      init-method="initialize"
                      p:poolConfig-ref="ldapPoolConfig"
                      p:blockWaitTime="${ldap.pool.blockWaitTime}"
                      p:validator-ref="searchValidator"
                      p:pruneStrategy-ref="pruneStrategy"
                      p:connectionFactory-ref="connectionFactory" />

                <bean id="ldapPoolConfig" class="org.ldaptive.pool.PoolConfig"
                      p:minPoolSize="${ldap.pool.minSize}"
                      p:maxPoolSize="${ldap.pool.maxSize}"
                      p:validateOnCheckOut="${ldap.pool.validateOnCheckout}"
                      p:validatePeriodically="${ldap.pool.validatePeriodically}"
                      p:validatePeriod="${ldap.pool.validatePeriod}" />

                <bean id="connectionFactory" class="org.ldaptive.DefaultConnectionFactory"
                      p:connectionConfig-ref="connectionConfig" />

                <bean id="connectionConfig" class="org.ldaptive.ConnectionConfig"
                      p:ldapUrl="${ldap.url}"
                      p:connectTimeout="${ldap.connectTimeout}"
                      p:useStartTLS="${ldap.useStartTLS}"
                      p:sslConfig-ref="sslConfig"/>

                <bean id="sslConfig" class="org.ldaptive.ssl.SslConfig">
                    <property name="credentialConfig">
                        <bean class="org.ldaptive.ssl.X509CredentialConfig"
                              p:trustCertificates="classpath:${ldap.trustedCert}" />
                    </property>
                </bean>

                <bean id="pruneStrategy" class="org.ldaptive.pool.IdlePruneStrategy"
                      p:prunePeriod="${ldap.pool.prunePeriod}"
                      p:idleTime="${ldap.pool.idleTime}" />

                <bean id="searchValidator" class="org.ldaptive.pool.SearchValidator" />

                <bean id="entryResolver"
                      class="org.jasig.cas.authentication.support.UpnSearchEntryResolver"
                      p:baseDn="${ldap.baseDn}" />


            </beans>

我的spring security.xml

        <beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

            <debug />


            <global-method-security secured-annotations="enabled" />

            <http auto-config="false" use-expressions="true"
                entry-point-ref="casAuthenticationEntryPoint">

                <custom-filter position="CAS_FILTER" ref="casAuthenticationFilter" />


                <intercept-url pattern="/faces/disclaimer**" access="permitAll" />
                <intercept-url pattern="/faces/searchCreditInstitution**"
                    access="permitAll" />
                <intercept-url pattern="/faces/searchParentInstitution**"
                    access="hasAnyRole('ROLE_CIR_EDITOR','ROLE_CIR_AUTHORISER')" />
                <intercept-url pattern="/faces/createCreditInstitution**"
                    access="hasAuthority('ROLE_CIR_EDITOR')" />
                <intercept-url pattern="/faces/authorisation**"
                    access="hasAuthority('ROLE_CIR_AUTHORISER')" />
                <intercept-url pattern="/faces/rejected**" access="hasAuthority('ROLE_CIR_EDITOR')" />
                <intercept-url pattern="/faces/pendingApproval**"
                    access="hasAuthority('ROLE_CIR_EDITOR')" />
                <intercept-url pattern="/faces/auditLog**"
                    access="hasAuthority('ROLE_CIR_AUTHORISER')" />
                <intercept-url pattern="/faces/enquiry**"
                    access="hasAnyRole('ROLE_CIR_EDITOR','ROLE_CIR_AUTHORISER','ROLE_CIR_XXXOPS')" />
                <intercept-url pattern="/faces/changePassword**"
                    access="hasAnyRole('ROLE_CIR_EDITOR','ROLE_CIR_AUTHORISER','ROLE_CIR_XXXOPS')" />
                <intercept-url pattern="/faces/dashboard**" access="ROLE_CIR_XXXOPS" />
                <intercept-url pattern="/resources**" access="permitAll" />
                <intercept-url pattern="/faces/javax.faces.resource**" access="permitAll" />
                <logout logout-url="/logout" logout-success-url="https://localhost:7002/cas/logout" />

            </http>

            <beans:bean id="serviceProperties"
                class="org.springframework.security.cas.ServiceProperties">
                <beans:property name="service"
                    value="https://localhost:7002/cir/j_spring_cas_security_check" />
                <beans:property name="sendRenew" value="false" />
            </beans:bean>

            <beans:bean id="casAuthenticationEntryPoint"
                class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
                <beans:property name="loginUrl" value="https://localhost:7002/cas/login" />
                <beans:property name="serviceProperties" ref="serviceProperties" />
            </beans:bean>

            <beans:bean id="casAuthenticationFilter"
                class="org.springframework.security.cas.web.CasAuthenticationFilter">
                <beans:property name="authenticationManager" ref="casAuthenticationManager" />
            </beans:bean>

            <authentication-manager alias="casAuthenticationManager">
                <authentication-provider ref="casAuthenticationProvider" />
            </authentication-manager>

            <beans:bean id="casAuthenticationProvider"
                class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
                <beans:property name="serviceProperties" ref="serviceProperties" />
                <beans:property name="ticketValidator" ref="ticketValidator" />
                <beans:property name="authenticationUserDetailsService"
                    ref="authenticationUserDetailsService" />
                <beans:property name="key" value="cir" />
            </beans:bean>

            <beans:bean id="ticketValidator"
                class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
                <beans:constructor-arg index="0"
                    value="https://localhost:7002/cas">
                </beans:constructor-arg>
            </beans:bean>

            <beans:bean id="authenticationUserDetailsService"
                class="XXX.cir.cas.authentication.XXXCasAuthenticationUserDetailsService" />

        </beans:beans>

我可以通过这种方式获得JSF托管bean中的Ldap角色,用户名,但不是国家

                SecurityContext ctx = SecurityContextHolder.getContext();

                UserDetails userDetails = (UserDetails)ctx.getAuthentication().getPrincipal();      

                System.out.println("Role of the ldaper : " + ctx.getAuthentication().getAuthorities());     

                String userRole = ctx.getAuthentication().getAuthorities(); 
答案

我没有使用Spring Security,但是一个选项可能是AttributeRepository,以便直接从cas获取属性而不是从应用程序中检索。您可以将一个attributeRepository添加到您的deployerContext(bean authenticationManager,属性credentialsToPrincipalResolvers:

 <bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" 
                p:attributeRepository-ref="attributeRepository"/>

以下豆类:

<bean id="attributeRepository" parent="baseAttributeRepository">
    <property name="personAttributeDaos">
        <list>
            <ref local="ldapAttributesByUid" />
        </list>
    </property>
</bean>  
<bean id="ldapAttributesByUid" parent="baseLdapAttributeRepository"
      class="org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao">
    <property name="queryAttributeMapping">
        <map>
            <entry key="username" value="uid" /> 
        </map>
    </property>
</bean>    
<bean id="baseLdapAttributeRepository" abstract="true"
      p:contextSource-ref="contextSource"
      p:baseDN="o=xxxxxx,dc=xxxxx"
      p:requireAllQueryAttributes="true">
    <property name="resultAttributeMapping">
        <map>
            <entry key="accountState" value="accountState" /> 
            <entry key="authId">
                <list>
                    <value>authId</value>
                    <value>Formatted Name</value>
                </list>
            </entry>
            <entry key="groupMembership" value="groupMembership" />
            <entry key="uid" value="uid" />
            <entry key="sn" value="sn" />
            <entry key="sn2" value="sn2" />
            <entry key="givenName" value="givenName" />
        </map>
    </property>
</bean>  

AFAIK,请记住必须使用SAML而不是CAS协议。更多信息在https://wiki.jasig.org/display/CASUM/Attributes

希望这可以帮助

以上是关于CAS认证后在JSF Managed Bean中获取LDAP属性的主要内容,如果未能解决你的问题,请参考以下文章

JSF Managed bean 中 List 的初始化

即使在刷新页面后,Firefox 也会在 JSF-Viewscoped-Managed-Bean 中保留数组的内容

Managed Bean中的EJB3.0 @EJB注释JSF2 Websphere 7是不可能的?

JSF中的循环managebean检测错误

JSF Managed Beans 不使用 spring 安全过滤器

cas