Hyunseok
프로그래밍/팀프로젝트 Spring boot3 - AuthenticationManager + Stackoverflow feat. UserDetailsService
2022. 12. 8. 20:01

사건의 발단..

이번에도 팀 시큐리티를 맡게 되었다

 

이번엔 기필코 깔끔하게 하겠다는 생각으로 임하게 되었는데..

각 파트 다 짜고 이제 로그인해보자! 하고 들어가는 순간...!!!!

 

아.... 제일 보기 싫은 에러가 떴다 

 

Filter는 타고 들어가는 걸 보니 일단 authentication으로 들어가는 시늉은 하는듯한데..

아마도 authentication에서 뭔가 문제가 생겼나 해서 authenticationmanager를 이리저리 건드렸고..

 

답이 안 나오던 나는 구글에 검색해보았다 

 

https://github.com/spring-projects/spring-framework/issues/29215#issuecomment-1263775300

 

AopTestUtils.getUltimateTargetObject results in stack overflow for proxy backed by LazyInitTargetSource · Issue #29215 · sprin

Security configuration class @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConf { @Bean public AuthenticationManager authenticationManagerBean(Authenticatio...

github.com

 

아..

 

유난히 이번에 이런 리포트가 많이 올라오는 이유는

 

다들 아마 WebSecurityConfigurerAdapter가 삭제되어

authenticationManager를 Bean으로 등록하여 쓰려하다 생기는 이유지 않을까

 

다들 아마 이렇게 등록하여 쓰고 있을 것이다

 

문제의 SecurityConfig - AuthenticationManager

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
    return authenticationConfiguration.getAuthenticationManager();
}

 

그럼 자연스레 AuthenticationManager는 authentication configuration에서 authenticationmanager를 불러와서 반환해줄 텐데..

 

잘 생각해보자

1. authentication configuration이 쓸 userDetailsService가 2개 이상일 경우

2. 일단 어떤 놈을 쓸지 모르니 일단  lazybean상태로 컨테이너에 빈을 가져다 넣는다

3. 여기서 authentication manager를 쓸려고 빈을 호출했는데

막상 빈에서 authentication configuration에서는 뭘 쓸지 모르는 상태라서 그냥 lazybean상태 그대로 authentication manager로 반환한다 

4. 당연히 다시 bean은 요청을 한다 "아니 내놓으라고 그래서 난 뭔데" > 무한반복

 

이러면서 stackoverflow가 발생한다 

 

여하튼.. 

지정해준 userDetailsService가 하나일 경우

그냥 userDetailsService 파일 위에다가 @Service나 @Component를 붙이면

지 알아서 authenticationconfiguration이 끌고 가는데.. 두 개 이상이면 저런 문제가 발생하지 않을까 

 

여하튼 두 개 이상일 경우 해결책의 제시로는 authenticationmanager의 내용을 직접 정의하는 것을 말하고 있다 

아래와 같이 말이다

 

해결을 위한 SecurityConfig - AuthenticationManager

    @Bean
    AuthenticationManager authenticationManager() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(customLoginService);
        provider.setPasswordEncoder(passwordEncoder());
        return new ProviderManager(provider);
    }

이렇게 직접 말이다..

 

이러면 뭐.. 확실히 문제가 생길 여지는 없어 보인다 

 

스프링은 역시.. 보면 볼수록 뭔가 아직 많이 생기고 있으며 모르는 게 많다고 느껴진다 

 

대체.. 그들은 어디까지 보고 개발하고 있는 걸까 


프로그래밍/팀프로젝트의 다른 글