복붙노트

[SPRING] 스프링 부트 LDAP 사용자 정의 UserDetails

SPRING

스프링 부트 LDAP 사용자 정의 UserDetails

스프링 부트 애플리케이션 (주석을 기반으로 한 구성)에서 LDAP 인증을 사용하고 있습니다. UserDetails 객체를 사용자 정의하고 싶습니다. 기본 UserDetails 구현은 LdapUserDetailsImpl입니다. 이 클래스를 확장하고 추가 iterfaces를 추가하고 스프링 보안에 바인딩하려고합니다. 내 config 클래스 :

@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();
    }
}

도와 줘서 고마워.

해결법

  1. ==============================

    1.내 솔루션 :

    내 솔루션 :

    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();
    }
    }
    
  2. from https://stackoverflow.com/questions/29007674/spring-boot-ldap-customize-userdetails by cc-by-sa and MIT license