LDAP Authentication Handler

本文档详细介绍了如何在CAS中配置LDAP认证,包括FastBindLdapAuthenticationHandler和BindLdapAuthenticationHandler的使用方法,以及如何配置连接池以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Including the Handler

In the pom.xml file for your CAS Maven2 WAR Overlay, add the following dependency:

< dependency >
      < groupId >org.jasig.cas</ groupId >
      < artifactId >cas-server-support-ldap</ artifactId >
      < version >${cas.version}</ version >
</ dependency >
 
<!--
   ONLY ADD THE BELOW DEPENDENCY IF POOLING IS NEEDED.
   SEE THE 'CONNECTION POOLING' SECTION FOR MORE INFO!
   <dependency>
       <groupId>commons-pool</groupId>
       <artifactId>commons-pool</artifactId>
       <version>${apache.commons.pool.version}</version>
   </dependency>
-->  
Icon

Version 3.3.5, due to a mistake in its build, included this by default. Prior and future versions do not include it by default.

You'll also need to create a new property in the pom file with the name "apache.commons.pool.version" and give the value of the apache commons pool version you intend to use, (i.e 1.5.6) if connection pooling is needed.

Core Classes

You need to decide how you would like CAS to authenticate the credentials. Should it merely attempt to authenticate to (bind to) the LDAP server using the credentials directly as the user? Or should it first look up the user in some subtree and then attempt to bind as that user? It is more efficient and more secure to use fastbind, but that is not always possible. This is explained in detail later in this document.

Both methods require you to configure an LDAP context bean: this is the configuration to access your directory. It is recommended to configure a new bean in the top list and reference that from the configuration of the AuthenticationHandler, as explained in the instructions on this page.

FastBindLdapAuthenticationHandler

Use this handler when a user DN may be directly composed from the username, e.g. uid=%u,ou=people,dc=vt,edu, where %u is the username provided on the CAS login form.

The FastBindLdapAuthenticationHandler supports the following properties:

  • filter - The filter property is the LDAP filter that will be used for the search. When constructing the filter, wherever you want the username to appear, place a "%u".
  • ignorePartialResultException - This property informs Spring LDAP to ignore PartialResultExceptions that may get thrown when connecting to an Active Directory.
  • contextSource - This is a reference to a LdapContextSource (see below) which will contain the settings for connecting to the LDAP server.

BindLdapAuthenticationHandler

This component performs a typical two-phase LDAP authentication process:

  1. Search for the user DN based on an arbitrary search filter.
  2. Construct the DN and bind with it using the password from the CAS login form.

Use this handler when the DN cannot be directly composed from the username, for example when the directory uid is an opaque identifier that is distinct from a memorable username or the common sense of username is based on an alternative attribute such as mail (email address). Since two LDAP operations are performed for every authentication, this method is inherently less efficient than FastBindLdapAuthenticationHandler and should be used when required.

The BindLdapAuthenticationHandler supports the following properties:

  • filter - The filter property is the LDAP filter that will be used for the search. When constructing the filter, wherever you want the username to appear, place a "%u".
  • ignorePartialResultException - This property informs LdapTemplate to ignore PartialResultExceptions that may get thrown when connecting to an Active Directory.
  • contextSource - LdapContextSource used for the LDAP bind operation. (And search in versions prior to 3.4.9).
  • searchContextSource - New in 3.4.9 LdapContextSource used for the LDAP search operation. This property is intended to support LDAP connection pooling for improved performance. See https://issues.jasig.org/browse/CAS-987 for data on performance improvements.
  • allowMultipleAccounts - Allows more than one account to be returned.
  • maxNumberOfResults - this is the maximum number of results we allow.
  • scope - One of the predefined "SearchControl" Scopes: SearchControls.OBJECT_SCOPE, SearchControls.ONELEVEL_SCOPE, or SearchControls.SUBTREE_SCOPE
  • searchBase - The search base is the node in the directory from where the search will be performed. (See LDAP Authentication with Multiple Search Bases if, well, you want to use more than one search base.)
  • timeout - This is the amount of time we are willing to wait for the search results to return.

Configuration

Note that all configuration should happen in cas-server-webapp/src/main/webapp/WEB-INF/deployerConfigContext.xml

Define a ContextSource

BindLdapAuthenticationHandler and FastBindLdapAuthenticationHandler require a Spring ContextSource to provide an LDAP connection on which to perform authentication operations.

< bean  id = "contextSource"  class = "org.springframework.ldap.core.support.LdapContextSource" >
   <!-- DO NOT enable JNDI pooling for context sources that perform LDAP bind operations. -->
   < property  name = "pooled"  value = "false" />
 
   <!--
     Although multiple URLs may defined, it's strongly recommended to avoid this configuration
     since the implementation attempts hosts in sequence and requires a connection timeout
     prior to attempting the next host, which incurs unacceptable latency on node failure.
     A proper HA setup for LDAP directories should use a single virtual host that maps to multiple
     real hosts using a hardware load balancer.
   -->
   < property  name = "url"  value = "ldaps://directory.example.com"  />
 
   <!--
     Manager credentials are only required if your directory does not support anonymous searches.
     Never provide these credentials for FastBindLdapAuthenticationHandler since the user's
     credentials are used for the bind operation.
   -->
   < property  name = "userDn"  value = "manager" />
   < property  name = "password"  value = "your_manager_password" />
 
   <!-- Place JNDI environment properties here. -->
   < property  name = "baseEnvironmentProperties" >
     < map >
       <!-- Three seconds is an eternity to users. -->
       < entry  key = "com.sun.jndi.ldap.connect.timeout"  value = "3000"  />
       < entry  key = "com.sun.jndi.ldap.read.timeout"  value = "3000"  />
 
       < entry  key = "java.naming.security.authentication"  value = "simple"  />
     </ map >
   </ property >
</ bean >

SSL Considerations

Icon
  • Make sure LDAP is connecting over SSL by using the ldaps protocol in the url above. The default ldaps port is 636. Failing to do so will generate LDAP authentication exceptions with the error code 49.
  • Please note that the JVM needs to trust the certificate of your SSL enabled LDAP server, else CAS will refuse to connect to your LDAP server. You can add the LDAP server's certificate to the JVM trust store ($JAVA_HOME/jre/lib/security/cacerts by default) to solve that issue.JVM will throw "unable to find valid certification path to requested target" exception when it doesn't find certificate sent by ldap server into keystore. There is a nice open source utility called InstallCert.java available from Sun which can add certificate returned by ldap server into your JVM keystore, use that to solve this problem.

Connection Pooling

The use of PoolingContextSource is strongly recommended in cases where it is supported. This component uses commons-pool object pooling and has performance characteristics suitable for HA environments. This is in stark contrast to the JNDI pooling feature enabled by com.sun.jndi.ldap.connect.pool=true that uses a strategy that will incur unacceptable latency in the case of LDAP node failure.

Connection pooling is supported for BindLdapAuthenticationHandler as of CAS 3.4.9. The searchContextSource property of BindLdapAuthenticationHandler may reference a ContextSource other than the one used for binds and is an ideal opportunity to leverage LDAP connection pooling for improved performance.

Sample Pooled ContextSource
< bean  id = "pooledContextSource"
   class = "org.springframework.ldap.pool.factory.PoolingContextSource"
   p:minIdle = "${ldap.pool.minIdle}"
   p:maxIdle = "${ldap.pool.maxIdle}"
   p:maxActive = "${ldap.pool.maxSize}"
   p:maxWait = "${ldap.pool.maxWait}"
   p:timeBetweenEvictionRunsMillis = "${ldap.pool.evictionPeriod}"
   p:minEvictableIdleTimeMillis = "${ldap.pool.idleTime}"
   p:testOnBorrow = "${ldap.pool.testOnBorrow}"
   p:testWhileIdle = "${ldap.pool.testWhileIdle}"
   p:dirContextValidator-ref = "dirContextValidator"
   p:contextSource-ref = "contextSource"  />
 
< bean  id = "dirContextValidator"
   class = "org.springframework.ldap.pool.validation.DefaultDirContextValidator"
   p:base = ""
   p:filter = "objectclass=*" >
   < property  name = "searchControls" >
     < bean  class = "javax.naming.directory.SearchControls"
       p:timeLimit = "1000"
       p:countLimit = "1"
       p:searchScope = "0"
       p:returningAttributes = ""  />
   </ property >
</ bean >

The following property values should serve as a reasonable starting point for pool tuning. They could simply be put into your cas.properties file alongside other property values. 

Sample Pool Configuration Properties
ldap.pool.minIdle= 3
ldap.pool.maxIdle= 5
ldap.pool.maxSize= 10
 
# Maximum time in ms to wait  for  connection to become available
# under pool exhausted condition.
ldap.pool.maxWait= 10000
 
# == Evictor configuration ==
 
# Period in ms at which evictor process runs.
ldap.pool.evictionPeriod= 600000
 
# Maximum time in ms at which connections can remain idle before
# they become liable to eviction.
ldap.pool.idleTime= 1200000
 
# == Connection testing settings ==
 
# Set to  true  to enable connection liveliness testing on evictor
# process runs.  Probably results in best performance.
ldap.pool.testWhileIdle= true
 
# Set to  true  to enable connection liveliness testing before every
# request to borrow an object from the pool.
ldap.pool.testOnBorrow= false

Practical Examples

BindLdapAuthenticationHandler without Pooling
< bean  class = "org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"
   p:filter = "mail=%u"
   p:searchBase = "ou=people,dc=example,dc=com"
   p:contextSource-ref = "contextSource"  />
BindLdapAuthenticationHandler with Pooling (3.4.9 and Above)
< bean  class = "org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"
   p:filter = "mail=%u"
   p:searchBase = "ou=people,dc=example,dc=com"
   p:contextSource-ref = "contextSource"
   p:searchContextSource-ref = "pooledContextSource"  />
Typical Active Directory Configuration
< bean  class = "org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"
   p:filter = "sAMAccountName=%u"
   p:searchBase = "cn=Users,dc=example,dc=com"
   p:contextSource-ref = "contextSource"
   p:searchContextSource-ref = "pooledContextSource"
   p:ignorePartialResultException = "true"  />
Integration with authenticationManager Bean in deployerConfigContext.xml
< bean  id = "authenticationManager"
   class = "org.jasig.cas.authentication.AuthenticationManagerImpl" >
   < property  name = "credentialsToPrincipalResolvers" >
     < list >
       < ref  bean = "usernameCredentialsResolver"  />
       < bean  class = "org.jasig.cas.authentication.principal.HttpBasedServiceCredentialsToPrincipalResolver"  />
     </ list >
   </ property >
 
   < 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"  />
 
     < bean  class = "org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"
       p:filter = "mail=%u"
       p:searchBase = "ou=people,dc=example,dc=com"
       p:contextSource-ref = "contextSource"
       p:searchContextSource-ref = "pooledContextSource"  />
     </ list >
   </ property >
 
   < property  name = "authenticationMetaDataPopulators" >
     < list >
       < bean
         class = "org.jasig.cas.authentication.SamlAuthenticationMetaDataPopulator"  />
     </ list >
   </ property >
</ bean >
DIGEST-MD5 Configuration
< bean  id = "saslMd5ContextSource"
   class = "org.springframework.ldap.core.support.LdapContextSource"
   p:url = "ldap://your.ldap.host" >
   < property  name = "baseEnvironmentProperties" >
     < map >
       < entry  key = "com.sun.jndi.ldap.connect.timeout"  value = "3000"  />
       < entry  key = "com.sun.jndi.ldap.read.timeout"  value = "3000"  />
       < entry  key = "java.naming.security.authentication"  value = "DIGEST-MD5"  />
     </ map >
   </ property >
</ bean >
 
<!-- Note the unusual form of the filter; DIGEST-MD5 uses a bare username for a credential -->
< bean  id = "saslMd5FastBindAuthHandler"
   class = "org.jasig.cas.adaptors.ldap.FastBindLdapAuthenticationHandler"
   p:filter = "%u"
   p:contextSource-ref = "saslMd5ContextSource"
/>

LDAP Attributes

There are cases where it is necessary to pull additional LDAP attributes (Eg. "mail") into the CAS principal (ie. user object). Please see Attributesfor more on this.
One such application is described in Google Apps from MS-AD using the 'mail' attribute

转载于:https://www.cnblogs.com/firejava/p/6432062.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值