问题描述
我在spring-boot应用程序中使用LDAP身份验证(基于注释的配置).我想自定义UserDetails对象.默认的UserDetails实现为 LdapUserDetailsImpl .我想扩展此类,添加一些额外的Iterfaces并绑定到spring-security中.我的配置类:
I'm using LDAP authentication in spring-boot application (configuration based on annotations). I would like to customize UserDetails object. Default UserDetails implementation is LdapUserDetailsImpl. I would like to extend this class and add some extra iterfaces and bind into spring-security.My config class:
@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对象):
UserService is custom method of authentication (it's database/jpa authentication).UserDetails accessor (when auth method is LDAP it's returning LdapUserDetailsImpl object):
@Component("activeUserAccessor")
public class ActiveUserAccessorImpl implements ActiveUserAccessor
{
public UserDetails getActiveUser()
{
return (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
}
谢谢您的帮助.
推荐答案
我的解决方案:
1.创建自定义UserDetailsContextMapper:
1.Create custom 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:
2.Bind UserDetailsContextMapper with LdapAuthenticationProviderConfigurer:
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()中返回扩展类.
3.Implement CustomLdapUserDetails (only isEnabled method is changed for now). You can add some extra interfaces, methods to CustomLdapUserDetails and return extended class in 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();
}
}
这篇关于春季启动LDAP定制UserDetails的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!