我在spring-boot应用程序中使用LDAP身份验证(基于注释的配置)。我想自定义UserDetails对象。默认的UserDetails实现是 LdapUserDetailsImpl 。我想扩展此类,添加一些额外的Iterfaces并绑定到spring-security中。我的配置类:
@Configuration protected static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter { @Autowired private UserService userService; @Autowired private Environment env; @Override public void init(AuthenticationManagerBuilder auth) throws Exception { AuthMethod authMethod = AuthMethod.valueOf(env.getRequiredProperty("auth_method")); switch (authMethod) { case LDAP: auth.ldapAuthentication() .userDnPatterns(env.getRequiredProperty("ldap.user_dn_patterns")) .groupSearchBase(env.getRequiredProperty("ldap.group_search_base")) .contextSource() .url(env.getRequiredProperty("ldap.url")); break; default: auth.userDetailsService(userService); break; } } @Bean public LdapContextSource contextSource () { LdapContextSource contextSource= new LdapContextSource(); contextSource.setUrl(env.getRequiredProperty("ldap.url")); contextSource.setUserDn(env.getRequiredProperty("ldap.user")); contextSource.setPassword(env.getRequiredProperty("ldap.password")); contextSource.afterPropertiesSet(); return contextSource; } }
UserService是自定义身份验证方法(它是数据库/ jpa身份验证)。UserDetails访问器(当auth方法是LDAP时,它返回LdapUserDetailsImpl对象):
@Component("activeUserAccessor") public class ActiveUserAccessorImpl implements ActiveUserAccessor { public UserDetails getActiveUser() { return (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); } }
感谢您的帮助。
我的解决方案:
1.创建自定义UserDetailsContextMapper:
@Bean public UserDetailsContextMapper userDetailsContextMapper() { return new LdapUserDetailsMapper() { @Override public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) { UserDetails details = super.mapUserFromContext(ctx, username, authorities); return new CustomLdapUserDetails((LdapUserDetails) details, env); } }; }
2.使用LdapAuthenticationProviderConfigurer绑定UserDetailsContextMapper:
auth.ldapAuthentication() .userDetailsContextMapper(userDetailsContextMapper()) .userDnPatterns(env.getRequiredProperty("ldap.user_dn_patterns")) .groupSearchBase(env.getRequiredProperty("ldap.group_search_base")) .contextSource() .url(env.getRequiredProperty("ldap.url"));
3.实现CustomLdapUserDetails(目前仅更改isEnabled方法)。您可以向CustomLdapUserDetails添加一些额外的接口,方法,并在ActiveUserAccessor.getActiveUser()中返回扩展类。
public class CustomLdapUserDetails implements LdapUserDetails { private static final long serialVersionUID = 1L; private LdapUserDetails details; private Environment env; public CustomLdapUserDetails(LdapUserDetails details, Environment env) { this.details = details; this.env = env; } public boolean isEnabled() { return details.isEnabled() && getUsername().equals(env.getRequiredProperty("ldap.username")); } public String getDn() { return details.getDn(); } public Collection<? extends GrantedAuthority> getAuthorities() { return details.getAuthorities(); } public String getPassword() { return details.getPassword(); } public String getUsername() { return details.getUsername(); } public boolean isAccountNonExpired() { return details.isAccountNonExpired(); } public boolean isAccountNonLocked() { return details.isAccountNonLocked(); } public boolean isCredentialsNonExpired() { return details.isCredentialsNonExpired(); } }