|
该版本仍在开发中,尚未被视为稳定。对于最新稳定版本,请使用 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();
| 如《对认证上下文执行作》中所述,某些设置可能需要你执行额外作以实现实际认证。详情请参见“对认证上下文执行作”。 |
| 不要自己编写自定义认证方法。请使用Spring 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来满足安全需求。它是一个功能齐全、成熟的安全框架,涵盖上述方面以及其他多个方面。