2017-12-12 11 views
1

기존의 작동중인 스프링 보안 (버전 3.2.10) XML 구성을 Java 기반 구성으로 변환하는 중입니다.스프링 보안에 인증 관리자를 삽입 할 때 위임 빌더가 null이 됨

<authentication-manager alias="authenticationManager"> 
    <authentication-provider ref="kerberosServiceAuthenticationProvider"/> 
    <authentication-provider ref="samlAuthenticationProvider"/> 
    <authentication-provider ref="pkiAuthenticationProvider"/> 
    <authentication-provider ref="openIdConnectAuthenticationProvider"/> 
</authentication-manager> 

내 자바 구성 동등한은 다음과 같습니다 : 인증 관리자가 다른 콩을 구성에서의 별명으로 불린다

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter 
{ 
    @Autowired 
    public void configure(AuthenticationManagerBuilder auth) throws Exception 
    { 
     auth.authenticationProvider(kerberosServiceAuthenticationProvider()) 
     .authenticationProvider(samlAuthenticationProvider()) 
     .authenticationProvider(pkiAuthenticationProvider()) 
     .authenticationProvider(openIdConnectAuthenticationProvider()); 
    } 
} 

, 나는 내가 대체하고 는 XML 구성 구성 인증 관리자가 있습니다 다음과 같이 authenticationmanagerbean을 덮어 썼습니다.

@Override 
@Bean(name = "authenticationManager") 
public AuthenticationManager authenticationManagerBean() throws Exception 
{ 
     return super.authenticationManagerBean(); 
} 

제안 된대로 그러나 How To Inject AuthenticationManager using Java Configuration in a Custom Filter ,이 콩의 작성에 다음과 같은 예외가 발생합니다 :

Caused by: java.lang.IllegalArgumentException: delegateBuilder cannot be null 
at org.springframework.util.Assert.notNull(Assert.java:112) 
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.<init>(WebSecurityConfigurerAdapter.java:426) 
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.authenticationManagerBean(WebSecurityConfigurerAdapter.java:220) 

대리인 빌더는 조각 슈퍼의 구현 (빈을 오버라이드 (override) 할 때 첫 번째 인수로 사용되는 인증 빌더입니다. authenticationManagerBean()). 이것은 null입니다.

public AuthenticationManager authenticationManagerBean() throws Exception { 
     return new AuthenticationManagerDelegator(authenticationBuilder, context); 
} 

그래서이 콩을 만들 때 뭔가 빠져있는 것 같습니다.

@Autowired 
public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) 
{...} 

을하지만 호출되지 않습니다 (그리고 오버라이드 (override)하는 것을 의미하지 않는 것)이 위임 빌더 만 WebSecurityConfigurerAdapter에서이 방법에 의해 설정된다. configure 메소드가 아직 호출되지 않은 것으로 나타났습니다. 분명히 뭔가 빠졌지 만 그게 뭔지 전혀 몰랐습니다.

+0

이미'configure (AuthenticationManagerBuilder auth)'로 빈을 노출했다. bean으로 두 개의 AuthenticationManager가 필요합니까? – dur

+0

아니요, 저는 아닙니다 :) 그렇다면 빌더에서 인증 관리자를 어떻게 bean으로 노출해야합니까? 내 보안 설정에서 자동 실행이 가능합니까? 왜냐하면 auth 객체를 다시 사용하고 getOrBuild()를 호출하는 것은 작동하지 않기 때문에 인증 메소드가 필요없는 다른 bean이 생성되기 전에 configure 메소드가 호출되지 않기 때문입니다. – DennisV

+0

유사한 질문은 my [answer] (https://stackoverflow.com/a/39259519/5277820)를 참조하십시오. – dur

답변

1

AuthenticationManagerBuilder에 문제가있는 경우 IllegalArgumentException: delegateBuilder cannot be null에 해결할 수없는 순환 bean 종속성이 있다고하는 오류가 발생합니다. 이것은 AuthenticationManagerBuilder으로하기 쉽습니다. 대신 AuthenticationManager을 Bean으로 노출하고 AuthenticationManagerBuilder을 전혀 사용하지 않는 것이 좋습니다.예를 들어

:

@Bean 
public ProviderManager authenticationManager() { 
    return new ProviderManager(Arrays.asList(
     kerberosServiceAuthenticationProvider(), 
     samlAuthenticationProvider(), 
     pkiAuthenticationProvider(), 
     openIdConnectAuthenticationProvider()); 
} 

문제가 계속 발생하는 경우, 당신은 또한에 정의를 허용 봄 보안의 인증 (즉 AuthenticationManagerAuthenticationProvider, PasswordEncoder 등) 정적을 정의하는 방법을 시도 할 수 있습니다 전체 클래스를 초기화하지 않고로드 할 수 있습니다. 문제가 계속되면 AuthenticationManagerAuthenticationProvider 구성을 별도의 구성 클래스로 옮기는 것이 좋습니다.

+0

첫 번째 제안은 실제로 문제를 해결했습니다! – DennisV

0

스프링 부트 2로 마이그레이션하는 동안 똑같은 오류가 발생했습니다 (이 과정에서 스프링 보안 4에서 스프링 보안 5.0.0으로 마이그레이션하고 XML 구성을 JavaConfig로 변환해야합니다). 이 내용이 귀하에게 해당하는지 잘 모르겠습니다. 봄 보안 5에서, 그 authenticationBuilder은 WebSecurityConfigurerAdapter의 방법으로 초기화 :

@Autowired 
public void setApplicationContext(ApplicationContext context) {..} 

그것은 따라서 문맥을 주입하는 시도해야합니다. 그러나 AuthenticationManager bean을 정의하는 my @ Bean-annotated 메소드는 항상 메소드 이전에 호출되어 사용자가 가진 것과 동일한 오류가 발생합니다.

public class MySecurityConfigurerAdapter extends WebSecurityConfigurerAdapter implements ApplicationContextAware { 
/*...*/ 
@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth 
      .authenticationProvider(dbAuthenticationProvider) 
      .authenticationProvider(otherAuthProvider); 
} 

@Bean(name = BeanIds.AUTHENTICATION_MANAGER) 
@Override 
public AuthenticationManager authenticationManagerBean() throws Exception { 
    return super.authenticationManagerBean(); 
} 
} 

내가 뒤에 정확한 이유를 설명 할 수 없다, 나는 새로운 "오른쪽"방법을 찾을 수 없습니다 : 은 단순히 다른 모든 전에 메소드의 호출을 강제로 ApplicationContextAware 인터페이스를 구현하는 것을 고정 문서에서 그것을 할 수는 있지만, 적어도 그것은 나를 위해 일했습니다.