Spring-LDAP验证用户

LDAP-Lightweight Directory Access Protocol。

LDAP通常被公司用作用户信息的中心资源库,同时也被当作一种认证服务。 它也可以为应用用户储存角色信息。

这里有很多如何对LDAP服务器进行配置的场景,所以Spring Security的LDAP提供器也是完全可配置的。 它使用为验证和角色检测提供了单独的策略接口,并提供了默认的实现,这些都是可配置成处理绝大多数情况。

你还是应该熟悉一下LDAP,在你在Spring Security使用它之前。 下面的链接提供了很好的概念介绍,也是一个使用免费的LDAP服务器建立一个目录http://www.zytrax.com/books/ldap/
的指南。 我们也应该熟悉一下通过JNDI API使用java访问LDAP。 我们没有在LDAP提供器里使用任何第三方LDAP库(Mozilla, JLDAP等等),但是还是用到了Spring LDAP,所以如果你希望自己进行自定义,对这个工程熟悉一下也是有好处的。

LDAP服务器可以是任何一个开源或商用的LDAP目录服务器,而客户端都可以使用同样的协议、客户端连接软件包和查询命令与LDAP服务器进行交互。

LDAP 目录是树形结构,目录有条目组成。条目是具有区别名DN(Distinguished Name)的属性(Attribute)集合,条目相当于表,DN相当于关系数据库表中的关键字(Primary Key),属性由类型(Type)和多个值(Values)组成。

DN-Distinguished Name,区别名,具有唯一性;DC-District,所属区域;OU-Organization Unit,所属组织;CN/UID-Common Name/Unique ID 名字。

如下图,uid-tsyroid的DN就是cn=tsyroid,ou=people,dc=syroidmanor,dc=com

 

本文使用Spring-LDAP进行用户验证,下载了1.3.1版本

applicationContex.xml配置文件

<bean id="contextSource"
class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldap://192.168.0.22:389" />
<property name="base" value="dc=ygsoft,dc=com" />
<property name="userDn" value="whuqin@yahoo.com" />
<property name="password" value="1234.abcd" />
<property name="referral" value="follow"></property>
</bean>

<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="contextSource" />
</bean>

<bean id="userDao" class="cn.com.ldap.UserDaoLdapImpl">
<property name="ldapTemplate">
<ref bean="ldapTemplate"/>
</property>
</bean>

userDn是用户区别名,格式应该为cn=xxx,ou=xxx,dc=xxx。而本文是由于公司LDAP服务器设置,使用用户的 userPrincipalName进行唯一标示。注意referral要设置为follow,否则会出现异常“Unprocessed Continuation Reference(s);”,设置为follow的意思好像是自动接下处理。。。。

UserDaoLdapImpl关键代码

private LdapTemplate ldapTemplate;
private ContextSource contextSource;
public void setLdapTemplate(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
public void setContextSource(ContextSource contextSource) {
this.contextSource = contextSource;
}
public boolean authenticate(String userName, String password) {
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectclass", "person")).and(new EqualsFilter("userPrincipalName", userName));
// Actual filter will differ depending on LDAP Server and schema
List<String> results = ldapTemplate.search("", filter.toString(),
new DnContextMapper());
if (results.size() != 1) return false;

DirContext ctx = null;
try {
ctx = contextSource.getContext(results.get(0), password);
return true;
} catch (Exception e) {
return false;
} finally {
LdapUtils.closeContext(ctx);
}
}
private final static class DnContextMapper extends
AbstractParameterizedContextMapper<String> {
@Override
protected String doMapFromContext(DirContextOperations ctx) {
return ctx.getNameInNamespace();
}
}

这样不管什么情况,都不会在控制台出现异常提示了。

发表评论