0

액세스 제어를 위해 객체 목록을 사용해야합니다. 이 목록을 가져 오는 쿼리는 매우 복잡하고 길기 때문에 사용자가 서버를 인증 할 때 사용자 개체에 캐시하고 싶습니다.LoadTimeWeaving없이 서비스를 사용하여 UserDetails 사용자 정의

public class LdapUserDetailsContextMapper implements UserDetailsContextMapper { 

private final org.slf4j.Logger log = LoggerFactory.getLogger(this.getClass()); 

private DataService dataService; 

public UserDetails mapUserFromContext(DirContextOperations ctx, String username, 
             Collection<? extends GrantedAuthority> authorities) { 

    AppUser user = new AppUser(); 
    user.setUsername(ctx.getStringAttribute("uid")); 
    user.setName(ctx.getStringAttribute("cn")); 
    user.setSurname(ctx.getStringAttribute("sn")); 
    user.setMail(ctx.getStringAttribute("mail")); 
    user.setRoleUser();  

user.setManaged(dataService.getManagedData(user.getMail())); 

        return user; 
       } 

문제는 내가 방법을 볼 수 없다는 것입니다 : 데이터를 사용자 개체를 채우기 위해

@Configuration 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

... 


     @Override 
     public void init(AuthenticationManagerBuilder auth) throws Exception { 
      String ldapURI = "ldap://" + ldaHost + ":" + ldapPort + "/" + ldapBasis; 

      DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapURI); 
      contextSource.setUserDn(ldapUser); 
      contextSource.setPassword(ldapPassword); 
      contextSource.afterPropertiesSet(); 

      LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> ldapAuthenticationProviderConfigurer = auth 
        .ldapAuthentication().userDetailsContextMapper(new LdapUserDetailsContextMapper()); 

      ldapAuthenticationProviderConfigurer 
        .userSearchFilter("(&(criteria={0}))") 
        .userSearchBase("ou=usersearchbase").contextSource(contextSource); 
     } 
} 

ContextMapper : 나는 시도하고 UserDetailService의 사용자 정의 구현이 WebSecurityConfig으로이 문제를 해결하기로 결정 이 프로세스에 DataService를 삽입하려면 ContextMapper 나 @Configure 클래스는 @Autowired를 불가능하게 만드는 관리 Bean이 아닙니다. LoadTimeWeaving을 피하려면이 방법을 사용하면 배포가 매우 어려워 질 수 있습니다. 다른 선택이 있습니까?

이 두 가지 유사한 문제점을 발견했습니다. Why is my Spring @Autowired field null?은 관리 클래스로 바뀔 수있는 컨트롤러 클래스에서 동일한 문제점을 가지고 있습니다. 다른 언급 된 두 솔루션 모두 나를 위해 작동하지 않았다 (dataService 항상 null) 및 Spring Boot, @Autowire into an unmanaged class using @Configurable and load time weaving 다시 LoadTimeWeaving 좋습니다.

는 또한 명백한 솔루션은 init 메소드에서 @Autowired를 사용하여 언급 찾았지만, 그 중 하나를 그냥 그것을 할

+1

그냥'LdapUserDetailsContextMapper'를 만드십시오. 새로운 인스턴스를 생성하는 대신 로직을'@ Bean' 주석 메소드에 넣고 호출하십시오. 당신은 것들을 overthinking하고 있습니다 ... –

+0

'@ Bean'은 '@ Service/@ Component etc'와 마찬가지로 싱글 톤을 선언하고 생성한다는 점에서 그렇게하지 않습니까? 나는 이것이 사실이라고 생각하여 결과를 내 WebSecurityConfig 클래스에 삽입 할 수 없었습니다. –

+1

그리고 왜 안 되죠. 당신의 매퍼 (mapper)에는 상태가 없습니다. 그것은 싱글 톤이 될 수 있습니다 ... 당신이 지금 그것을 선언 할 때, 그것이 싱글 톤일지라도, 유일한 차이점은 그것이 스프링 관리가 아니라는 것입니다. –

답변

1

을 (주입 된 DataService에 함께 ContextMapper-생성자를 호출하려고) 작업을 얻을 수 없었다 봄 관리 콩.

@Configuration 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

... 


     @Override 
     public void init(AuthenticationManagerBuilder auth) throws Exception { 
      String ldapURI = "ldap://" + ldaHost + ":" + ldapPort + "/" + ldapBasis; 

      DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(ldapURI); 
      contextSource.setUserDn(ldapUser); 
      contextSource.setPassword(ldapPassword); 
      contextSource.afterPropertiesSet(); 

      LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder> ldapAuthenticationProviderConfigurer = auth 
        .ldapAuthentication().userDetailsContextMapper(userDetailsContextMapper()); 

      ldapAuthenticationProviderConfigurer 
        .userSearchFilter("(&(criteria={0}))") 
        .userSearchBase("ou=usersearchbase").contextSource(contextSource); 
     } 
    @Bean 
    public LdapUserDetailsContextMapper userDetailsContextMapper() { 
     return new LdapUserDetailsContextMapper(); 
    } 
} 

그리고 @Autowired으로 LdapUserDetailsContextMapper 내 자신의 분야를 주석을 달 수 있습니다.