原创

CAS4.0.0集成OpenLdap并返回用户信息配置讲解

        最近公司要求CAS3.5.2支持saml而目前使用的版本不支持saml,因此升级成4.0.0版本,但是升级cas到cas4.0.0版本后也需要支持ldap,网上关于4.0.0版本的文章很少而支持ldap的少之又少,本人花了很长的时间整理了关于cas4集成ldap的完美解决方案的文章,如果对该文章有什么问题,欢迎在素文宅www.yoodb.com留言询问。


首先下载cas4版本,cas-server服务端,其官方下载地址:https://github.com/apereo/cas/tree/4.0.x

在cas-server-webapp工程中的pom.xml文件中,添加以下依赖关系:

<dependency>
     <groupId>org.jasig.cas</groupId>
     <artifactId>cas-server-support-ldap</artifactId>
     <version>${cas.version}</version>
</dependency>


关于ssl的方面略过(此不可以跳过),修改tomcat里面的8443端口内容,修改成如下:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" 
               maxThreads="150" scheme="https" secure="true" 
               clientAuth="false" sslProtocol="TLS" 
               keystoreFile="d:/keys/yoodb.keystore"      <!--你的证书所放的位置-->
               keystorePass="password" />         <!--认证证书的密码-->



4.0.0的版本需要增加许多配置,逐步增加配置首先需要的是修改认证入口,编辑deployerConfigContext.xml文件,具体配置如下:

    <bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">
        <constructor-arg>
            <map>
                <!--
                   | IMPORTANT
                   | Every handler requires a unique name.
                   | If more than one instance of the same handler class is configured, you must explicitly
                   | set its name to something other than its default name (typically the simple class name).
                   -->
                <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />
                <entry key-ref="ldapAuthHandler" value-ref="primaryPrincipalResolver" /> <!--新增ldap认证的入口 -->
            </map>
        </constructor-arg>

        <!-- Uncomment the metadata populator to allow clearpass to capture and cache the password
             This switch effectively will turn on clearpass.
        <property name="authenticationMetaDataPopulators">
           <util:list>
              <bean class="org.jasig.cas.extension.clearpass.CacheCredentialsMetaDataPopulator"
                    c:credentialCache-ref="encryptedMap" />
           </util:list>
        </property>
        -->

        <!--
           | Defines the security policy around authentication. Some alternative policies that ship with CAS:
           |
           | * NotPreventedAuthenticationPolicy - all credential must either pass or fail authentication
           | * AllAuthenticationPolicy - all presented credential must be authenticated successfully
           | * RequiredHandlerAuthenticationPolicy - specifies a handler that must authenticate its credential to pass
           -->
        <property name="authenticationPolicy">
            <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />
        </property>
    </bean>

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

    <!--
       | TODO: Replace this component with one suitable for your enviroment.
       |
       | This component provides authentication for the kind of credential used in your environment. In most cases
       | credential is a username/password pair that lives in a system of record like an LDAP directory.
       | The most common authentication handler beans:
       |
       | * org.jasig.cas.authentication.LdapAuthenticationHandler
       | * org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler
       | * org.jasig.cas.adaptors.x509.authentication.handler.support.X509CredentialsAuthenticationHandler
       | * org.jasig.cas.support.spnego.authentication.handler.support.JCIFSSpnegoAuthenticationHandler
       -->
    <!-- Required for proxy ticket mechanism -->
    <bean id="proxyPrincipalResolver"
          class="org.jasig.cas.authentication.principal.BasicPrincipalResolver" />


然后新增ldap中的LDAP配置文件,修改deployerConfigContext.xml文件,具体代码如下:

    <!-- begin -->
       <bean id="ldapAuthHandler" class="org.jasig.cas.authentication.LdapAuthenticationHandler"
              c:authenticator-ref="authenticator">
        </bean>
        
        <bean id="entryResolver"
          class="org.jasig.cas.authentication.support.UpnSearchEntryResolver"
          p:connectionFactory-ref="bindPooledLdapConnectionFactory" 
          p:baseDn="ou=users,dc=CMP" />
        
        <bean id="authenticator" class="org.ldaptive.auth.Authenticator"  
              c:resolver-ref="dnResolver"  
              c:handler-ref="authHandler"
              p:entryResolver-ref="entryResolver"/>  
              
<bean id="dnResolver" class="org.ldaptive.auth.PooledSearchDnResolver"
          p:baseDn="ou=users,dc=CMP"
          p:allowMultipleDns="false"
          p:connectionFactory-ref="searchPooledLdapConnectionFactory"
          p:userFilter="(uid={user})" />
          
        <bean id="searchPooledLdapConnectionFactory"
          class="org.ldaptive.pool.PooledConnectionFactory"
          p:connectionPool-ref="searchConnectionPool" />

   <bean id="searchConnectionPool" parent="abstractConnectionPool"
         p:connectionFactory-ref="searchConnectionFactory" />
   <bean id="searchConnectionFactory"
         class="org.ldaptive.DefaultConnectionFactory"
         p:connectionConfig-ref="searchConnectionConfig" />
   <bean id="searchConnectionConfig" parent="abstractConnectionConfig"
         p:connectionInitializer-ref="bindConnectionInitializer" />

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

   <bean id="bindPooledLdapConnectionFactory"
         class="org.ldaptive.pool.PooledConnectionFactory"
         p:connectionPool-ref="bindConnectionPool" />
   <bean id="bindConnectionPool" parent="abstractConnectionPool"
         p:connectionFactory-ref="bindConnectionFactory" />
   <bean id="bindConnectionFactory"
         class="org.ldaptive.DefaultConnectionFactory"
         p:connectionConfig-ref="bindConnectionConfig" />

    <bean id="bindConnectionConfig" parent="abstractConnectionConfig" />


        <bean  id="abstractConnectionPool" abstract="true"
              class="org.ldaptive.pool.BlockingConnectionPool"
              init-method="initialize"
              p:poolConfig-ref="ldapPoolConfig"
              p:blockWaitTime="3000"
              p:validator-ref="searchValidator"
              p:pruneStrategy-ref="pruneStrategy"
              p:connectionFactory-ref="connectionFactory" />


        <bean id="ldapPoolConfig" class="org.ldaptive.pool.PoolConfig"
              p:minPoolSize="3"
              p:maxPoolSize="10"
              p:validateOnCheckOut="false"
              p:validatePeriodically="true"
              p:validatePeriod="300" />


        <bean id="abstractConnectionConfig" abstract="true"
          class="org.ldaptive.ConnectionConfig"
              p:ldapUrl="ldap://127.0.0.1:1389"  
              p:connectTimeout="3000"    
              p:connectionInitializer-ref="bindConnectionInitializer"
              p:useStartTLS="false"
              p:useSSL="false"/><!-- 取消支持ssl,默认为false -->


      <!-- <bean id="sslConfig" class="org.ldaptive.ssl.SslConfig">
            <property name="credentialConfig">
                <bean class="org.ldaptive.ssl.X509CredentialConfig"
                      p:trustCertificates="d:/keys/yoodb.keystore" />
            </property>
        </bean>  -->
<bean id="bindConnectionInitializer"
         class="org.ldaptive.BindConnectionInitializer"
         p:bindDn="cn=DMer">
       <property name="bindCredential">
           <bean class="org.ldaptive.Credential"
                 c:password="123456" />
       </property>
   </bean>

    <bean id="pruneStrategy" class="org.ldaptive.pool.IdlePruneStrategy"
              p:prunePeriod="300"
              p:idleTime="600" />

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

    <bean id="primaryPrincipalResolver"
          class="org.jasig.cas.authentication.principal.PersonDirectoryPrincipalResolver"
          p:returnNullIfNoAttributes="true" >
        <property name="attributeRepository" ref="attributeRepository" />
    </bean>
<bean id="searchControls"
          class="javax.naming.directory.SearchControls"
          p:searchScope="1"
          p:countLimit="2" />

    <bean id="attributeRepository"  
      class="org.jasig.cas.persondir.LdapPersonAttributeDao"  
      p:connectionFactory-ref="searchPooledLdapConnectionFactory"  
      p:baseDN="ou=users,dc=CMP" p:searchControls-ref="searchControls" p:searchFilter="uid={0}"> 
        <property name="queryAttributeMapping">
           <map>
                <entry key="username" value="uid" />
            </map>
        </property>
        <property name="resultAttributeMapping">
            <map>
                <entry key="cn" value="cn" />
                <entry key="sn" value="sn" />
                <entry key="city" value="city" />
                <entry key="country" value="country"/>
                <entry key="mail" value="mail"/>
                <entry key="mobile" value="mobile"/>
                <entry key="province" value="province"/>
                <entry key="uid" value="uid" />

            </map>
        </property>
</bean>
    <!-- end -->



注意:org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao 这个类的目的将Principal与后端的LDAP目录进行匹配(queryAttributeMapping属性,将Principal的username域与LDAP查询的uid属性相匹配,即queryAttributeMapping属性中必须<entry key="username" value="uid" />配置)。提供的baseDN属性要使用LDAP进行查询(uid=ldapguest) ,并且属性要从匹配的条目进行读取。 匹配到Principal属性使用resultAttributeMapping属性中的键值对——我们将LDAP的cn和sn属性匹配到有意义的名字,而description属性匹配到role属性,而role属性就是GrantedAuthorityFromAssertionAttributesUserDetailsService要进行查找的。到这一步cas4集成ldap并返回更多用户信息就完成了。


CAS4.0.0关于service的存储方式有以下几种:

1)InMemoryServiceRegistryDaoImpl

2)JsonServiceRegistryDao

3)JpaServiceRegistryDaoImpl:如果启用了oauth,因为每一个第三方都被认为是一个service,最好存储在数据库中,管理方便

4)MongoServiceRegistryDao


CAS4.0.0默认配置是使用InMemoryServiceRegistryDaoImpl,此步骤主要是将service服务存储至数据库中,如果只是cas4.0.0集成ldap并返回更多数据,上述步骤操作完之后即可此步骤省略,如果需要将service服务存储至数据库,修改deployerConfigContext.xml文件具体代码如下:

 <!-- 
    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 class="org.jasig.cas.services.JpaServiceRegistryDaoImpl" id="serviceRegistryDao" />
    
    <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
    id="factoryBean"
    p:dataSource-ref="dataSource"
    p:jpaVendorAdapter-ref="jpaVendorAdapter"
    p:packagesToScan-ref="packagesToScan">
    <property name="jpaProperties">
      <props>
        <prop key="hibernate.dialect">${database.dialect}</prop>
        <prop key="hibernate.hbm2ddl.auto">update</prop>
        <prop key="hibernate.jdbc.batch_size">${database.batchSize}</prop>
      </props>
    </property>
  </bean>

  <bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource"
    id="dataSource"
    p:driverClass="${database.driverClass}"
    p:username="${database.user}"
    p:password="${database.password}"
    p:url="${database.url}" />
    
    <util:list id="packagesToScan">
   <value>org.jasig.cas.services</value>
   <value>org.jasig.cas.ticket</value>
 </util:list>
    
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
    id="jpaVendorAdapter"
    p:generateDdl="true"
    p:showSql="true" />
    
    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"
    p:entityManagerFactory-ref="factoryBean" />
    
    
    <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 class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
</beans>


在cas-server-webapp工程中cas.properties文件增加关于数据库配置信息,具体配置如下:

#oracle 连接数据库配置
database.driverClass=oracle.jdbc.driver.OracleDriver
database.user=admin
database.password=123456
database.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
database.dialect=org.hibernate.dialect.Oracle9Dialect

#mysql 连接数据库配置
#database.driverClass=com.mysql.jdbc.Driver
#database.dialect=org.hibernate.dialect.MySQLDialect
#database.url=jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=utf8
#database.user=root
#database.password=123456

database.batchSize=1

关注下方微信公众号“Java精选”(w_z90110),回复关键字领取资料:如HadoopDubboCAS源码等等,免费领取资料视频和项目。 

涵盖:程序人生、搞笑视频、算法与数据结构、黑客技术与网络安全、前端开发、Java、Python、Redis缓存、Spring源码、各大主流框架、Web开发、大数据技术、Storm、Hadoop、MapReduce、Spark、elasticsearch、单点登录统一认证、分布式框架、集群、安卓开发、iOS开发、C/C++、.NET、Linux、Mysql、Oracle、NoSQL非关系型数据库、运维等。

相关推荐

评论

  1. #1

    呦西 (2017/07/15 21:27:23)回复
    目前正在集成Ldap,之前集成Oauth2.0已经成功拉,感谢站长分享的文章。评论一下,略表感谢!

    路人甲 (2017/09/25 21:26:36)回复
    有问题可以留言,CAS感觉还行不错的SSO单点登录系统

  2. #2

    随缘 (2017/05/27 14:43:39)回复
    我的评论是这样的哈哈

  3. #3

    呦呦人生 (2017/05/27 14:40:35)回复
    无聊可以用于打发时间,不要调皮捣蛋阿!

    路人甲 (2017/09/25 21:43:57)回复
    哈哈,没事多学学技术有助于提升技术水平,不要没事瞎玩。

分享:

支付宝

微信