|
该版本仍在开发中,尚未被视为稳定。对于最新稳定版本,请使用 Spring LDAP 4.0.0! |
使用 Spring LDAP 的用户认证
本节介绍使用 Spring LDAP 的用户认证。它包含以下主题:
基本认证
而核心功能则是上下文来源就是提供DirContext用于LdapClient和LdapTemplate你也可以用它来对LDAP服务器进行身份验证。这getContext(principal, credentials)方法上下文来源正是如此。它构造了一个DirContext根据上下文来源配置并通过提供的主体和凭证对上下文进行认证。自定义认证方法可以如下示例:
public boolean authenticate(String userDn, String credentials) {
DirContext ctx = null;
try {
ctx = contextSource.getContext(userDn, credentials);
return true;
} catch (Exception e) {
// Context creation failed - authentication did not succeed
logger.error("Login failed", e);
return false;
} finally {
// It is imperative that the created DirContext instance is always closed
LdapUtils.closeContext(ctx);
}
}
这用户Dn供应给证实方法必须是用户的完整DN才能认证(无论基础在上下文来源).通常你需要基于(例如)用户名进行LDAP搜索以获取这个DN。以下示例展示了如何实现:
private String getDnForUser(String uid) {
List<String> result = ldapClient.search()
.query(query().where("uid").is(uid))
.toList((Object ctx) -> ((DirContextOperations) ctx).getNameInNamespace());
if(result.size() != 1) {
throw new RuntimeException("User not found or not unique");
}
return result.get(0);
}
这种做法也有一些缺点。你必须关注用户的DN,只能搜索用户的uid,搜索始终从树根(空路径)开始。更灵活的方法可以让你指定搜索基、搜索筛选器和凭证。Spring LDAP 包含了LdapClient这提供了这一功能。
使用这种方法后,认证方式变得简单,如下:
ldapClient.authenticate().query(query().where("uid").is("john.doe")).password("secret").execute();
| 如《在认证上下文执行作》中所述,某些设置可能需要你进行额外作才能实现真正的认证。详情请参见“对认证上下文执行作”。 |
| 不要自己编写自定义认证方法。使用春季LDAP提供的课程。 |
对认证上下文执行作
一些认证方案和LDAP服务器要求对创建的设备执行某些作DirContext实际认证的实例。你应该测试一下,确保你的服务器设置和认证方案表现如何。如果未这样做,用户可能会被接入你的系统,无论你提供的DN和凭证如何。以下示例展示了一种认证方法的朴素实现,其中硬编码为查找作是在经过认证的上下文中执行的:
public boolean myAuthenticate(String userDn, String credentials) {
DirContext ctx = null;
try {
ctx = contextSource.getContext(userDn, credentials);
// Take care here - if a base was specified on the ContextSource
// that needs to be removed from the user DN for the lookup to succeed.
ctx.lookup(userDn);
return true;
} catch (Exception e) {
// Context creation failed - authentication did not succeed
logger.error("Login failed", e);
return false;
} finally {
// It is imperative that the created DirContext instance is always closed
LdapUtils.closeContext(ctx);
}
}
如果作能作为回调接口的实现提供,而不是总是限制作为查找.春季LDAP包括AuthenticatedLdapEntryContextMapper回调接口及其对应的证实方法。
该方法允许在认证上下文上执行任意作,具体如下:
AuthenticatedLdapEntryContextMapper<DirContextOperations> mapper = new AuthenticatedLdapEntryContextMapper<DirContextOperations>() {
public DirContextOperations mapWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification) {
try {
return (DirContextOperations) ctx.lookup(ldapEntryIdentification.getRelativeName());
}
catch (NamingException e) {
throw new RuntimeException("Failed to lookup " + ldapEntryIdentification.getRelativeName(), e);
}
}
};
ldapClient.authenticate().query(query().where("uid").is("john.doe")).password("secret").execute(mapper);
使用 Spring Security
虽然前述方法对于简单的认证场景可能足够,但该领域的需求通常迅速扩展。涉及多个方面,包括认证、授权、网页集成、用户上下文管理等。如果你怀疑要求可能超出简单的认证,那么你绝对应该考虑使用Spring Security来实现安全。它是一个功能齐全、成熟的安全框架,涵盖了上述方面以及其他若干方面。