Java 如何使用LDAP电子邮件或移动设备而不是用户名进行身份验证? 如何使用LDAP电子邮件或手机而不是用户名进行身份验证?
在Spring boot 1.5.9应用程序中,我使用Java 如何使用LDAP电子邮件或移动设备而不是用户名进行身份验证? 如何使用LDAP电子邮件或手机而不是用户名进行身份验证?,java,spring,spring-security,ldap,spring-security-ldap,Java,Spring,Spring Security,Ldap,Spring Security Ldap,在Spring boot 1.5.9应用程序中,我使用Spring security ldap,并使用默认的LdapUserDetailsManager类登录 默认情况下,它使用loadUserByUsername方法 我有两种类型的用户: 后台:应该能够使用用户名登录(或者在最坏的情况下,使用电子邮件) 客户:应该能够使用手机,电子邮件 这是org.springframework.security.ldap.userdetails.LdapUserDetailsManager的内容: 公共
Spring security ldap
,并使用默认的LdapUserDetailsManager
类登录
默认情况下,它使用loadUserByUsername
方法
我有两种类型的用户:
- 后台:应该能够使用
用户名登录(或者在最坏的情况下,使用电子邮件)
- 客户:应该能够使用
,手机
电子邮件
公共类LdapUserDetailsManager实现UserDetailsManager{
私有最终日志记录器=LogFactory.getLog(LdapUserDetailsManager.class);
/**
*将用户名映射到LDAP可分辨名称的策略。将使用
*在构建DNs以创建新用户等时。
*/
LdapUsernameToDnMapper usernameMapper=新的默认LdapUsernameToDnMapper(“cn=users”,
“uid”);
/**用于存储组的DN*/
private DifferentiedName groupSearchBase=新的DifferentiedName(“cn=组”);
/**密码属性名称*/
私有字符串passwordAttributeName=“userPassword”;
/**与组的角色名称相对应的属性*/
私有字符串groupRoleAttributeName=“cn”;
/**包含组成员的属性*/
私有字符串groupMemberAttributeName=“uniquemember”;
私有最终字符串rolePrefix=“ROLE_389;”;
/**用于用户搜索的模式。{0}是用户的DN*/
私有字符串groupSearchFilter=“(uniquemember={0})”;
/**
*用于从LDAP上下文(用户名)创建UserDetails对象的策略
*和权限列表。应将其设置为与所需的用户详细信息匹配
*实施。
*/
私有UserDetailsContextMapper userDetailsMapper=new InetOrgPersonContextMapper();
私有最终LdapTemplate模板;
/**用于从属性列表创建一组角色的默认上下文映射器*/
私有属性映射角色映射=新属性映射(){
公共对象mapFromAttributes(属性属性)引发NamingException{
Attribute roleAttr=attributes.get(groupRoleAttributeName);
namingumeration ne=roleAttr.getAll();
//断言ne.hasMore();
对象组=ne.next();
字符串角色=group.toString();
返回新的SimpleGrantedAuthority(rolePrefix+role.toUpperCase());
}
};
私有字符串[]attributesToRetrieve;
公共LdapUserDetailsManager(ContextSource ContextSource){
模板=新的LdapTemplate(contextSource);
}
公共用户详细信息loadUserByUsername(字符串用户名){
DifferentizedName dn=usernameMapper.buildDn(用户名);
列表权限=GetUserAuthories(dn,用户名);
debug(“正在加载用户“+”用户名“+”和DN“+”DN“+””);
DirContextAdapter userCtx=loadUserAsContext(dn,用户名);
返回userDetailsMapper.mapUserFromContext(userCtx、用户名、权限);
}
private DirContextAdapter loadUserAsContext(最终区分名称dn,
最终字符串(用户名){
return(DirContextAdapter)模板.executeReadOnly(新ContextExecutor(){
公共对象executeWithContext(DirContext ctx)引发NamingException{
试一试{
Attributes attrs=ctx.getAttributes(dn,attributesToRetrieve);
返回新的DirContextAdapter(attrs,LdapUtils.getFullDn(dn,ctx));
}
catch(NameNotFoundException-notFound){
抛出新UsernameNotFoundException(
“用户”+用户名+“未找到”,未找到);
}
}
});
}
/**
*更改当前用户的密码。用户名从
*安全上下文。
*
*如果提供了旧密码,则将以用户身份重新绑定以进行更新,
*从而使用用户权限修改密码。如果
*oldPassword
为空,将使用标准密码尝试更新
*由上下文源提供的读/写上下文。
*
*
*@param oldPassword旧密码
*@param newPassword密码的新值。
*/
public void changePassword(最终字符串oldPassword,最终字符串newPassword){
身份验证=SecurityContextHolder.getContext()
.getAuthentication();
Assert.notNull(
认证,
“在安全上下文中找不到身份验证对象。无法更改当前用户的密码!”);
字符串username=authentication.getName();
logger.debug(“更改用户的密码’”+用户名);
最终区分名称dn=usernameMapper.buildDn(用户名);
最终修改项[]密码更改=新修改项[]{new ModificationItem(
DirContext.REPLACE_属性,新的基本属性(passwordAttributeName,
新密码;
如果(oldPassword==null){
template.modifyAttributes(dn、passwordChange);
返回;
}
template.executeReadWrite(新ContextExecutor(){
公共对象executeWithContext(DirContext dirCtx)引发NamingException{
LdapContext ctx=(LdapContext)dirCtx;
ctx.removeFromEnvironment(“com.sun.jndi.ldap.connect.pool”);
ctx.addToEnvironment(Context.SECURITY\u委托人,
LdapUtils.getFullDn(dn,ctx.toString());
ctx.addToEnvironment(Context.SECU