一、CAS集成LDAP认证
1、客户端仍然使用上一篇文章中cas-test和cas-test2
2、相关依赖的jar
spring-ldap-1.3.1.RELEASE-all.jar
cas-server-support-ldap-3.5.2.jar
3、修改deployerConfigContext.xml文件
将下面的
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
替换为如下
<!-- 通过LDAP的方式检验用户 -->
<bean
class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler">
<property name="filter" value="myLoginName=%u" />
<property name="searchBase" value="ou=USER,ou=ISC,o=SGCC" />
<property name="contextSource" ref="contextSource" />
</bean>
并添加相应的LDAP的配置信息
<!-- LDAP配置 -->
<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="anonymousReadOnly" value="false" />
<property name="password" value="admin" />
<property name="pooled" value="true" />
<property name="urls">
<list>
<value>ldap://192.168.1.214:389/</value>
</list>
</property>
<!-- 如果是老版本,这里应该用的是userName,而不是userDn -->
<property name="userDn" value="cn=admin,ou=users,o=services" />
<property name="baseEnvironmentProperties">
<map>
<entry>
<!--none 端口 389-->
<!--ssl 端口 636-->
<key>
<value>java.naming.security.protocol</value>
</key>
<value>none</value>
</entry>
<entry>
<key>
<value>java.naming.security.authentication</value>
</key>
<value>simple</value>
</entry>
</map>
</property>
</bean>
二、认证原理
关键代码
BindLdapAuthenticationHandler.java
protected final boolean authenticateUsernamePasswordInternal(final UsernamePasswordCredentials credentials) throws AuthenticationException {
final List<String> cns = new ArrayList<String>();
final SearchControls searchControls = getSearchControls();
final String base = this.searchBase;
final String transformedUsername = getPrincipalNameTransformer().transform(credentials.getUsername());
final String filter = LdapUtils.getFilterWithValues(getFilter(), transformedUsername);
this.getLdapTemplate().search(
new SearchExecutor() {
public NamingEnumeration executeSearch(final DirContext context) throws NamingException {
return context.search(base, filter, searchControls);
}
},
new NameClassPairCallbackHandler(){
public void handleNameClassPair(final NameClassPair nameClassPair) {
cns.add(nameClassPair.getNameInNamespace());
}
});
if (cns.isEmpty()) {
log.info("Search for " + filter + " returned 0 results.");
return false;
}
if (cns.size() > 1 && !this.allowMultipleAccounts) {
log.warn("Search for " + filter + " returned multiple results, which is not allowed.");
return false;
}
for (final String dn : cns) {
DirContext test = null;
String finalDn = composeCompleteDnToCheck(dn, credentials);
try {
this.log.debug("Performing LDAP bind with credential: " + dn);
test = this.getContextSource().getContext(
finalDn,
getPasswordEncoder().encode(credentials.getPassword()));
if (test != null) {
return true;
}
} catch (final NamingSecurityException e) {
log.info("Failed to authenticate user {} with error {}", credentials.getUsername(), e.getMessage());
throw handleLdapError(e);
} catch (final Exception e) {
this.log.error(e.getMessage(), e);
throw handleLdapError(e);
} finally {
LdapUtils.closeContext(test);
}
}
return false;
}
---------------------------------------------------------华丽的分割线-----------------------------------------------------------
OpenLdap安装图文说明,参看附件