3

Я использую аутентификацию LDAP в приложении весной загрузки (конфигурация на основе аннотаций). Я хотел бы настроить объект UserDetails. Реализация по умолчанию UserDetails - LdapUserDetailsImpl. Я хотел бы расширить этот класс и добавить некоторые дополнительные итерации и привязать к Spring-security. Мой конфиг класс:Spring-boot LDAP customize UserDetails

@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 сбруя (при аутентификации метод LDAP, что возвращается объект LdapUserDetailsImpl):

@Component("activeUserAccessor") 
public class ActiveUserAccessorImpl implements ActiveUserAccessor 
{ 
    public UserDetails getActiveUser() 
    { 
     return (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    } 
} 

Спасибо за вашу помощь.

ответ

10

Мое решение:

1.Create пользовательских 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.Bind UserDetailsContextMapper с 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.Implement 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(); 
} 
}