스프링 시큐리티 순환참조 오류 & AuthenticationManager not must be specified

조은지·2023년 8월 25일

참조 링크
https://yoo11052.tistory.com/134

서론

현재 프로젝트에서는 spring security 버전 6 을 사용 중이다.
SecurityConfig에서 WebSecurityConfigurerAdapter을 상속받지 않고, filterChain 으로 설정을 하는 방식으로 바뀌면서 또 한가지 바뀐 것이 있었다.

바로 AuthenticationManager를 오버라이드 받지 못한다는 것..

AuthenticationManagerBuilder를 따로 만들어주는 방법이 있다던데.. 이해가 잘 가지 않았고, 내 프로젝트의 경우 Provider가 딱 한개+ 단순히 provider한테 검증 요청해달라고 하는게 끝인 애여서 CustomAuthenticationManger를 만들어주기로 했다.

발생한 오류 1 - 순환 참조 오류

  1. WebSecurityConfig에서 PasswordEncoder를 빈으로 등록해주었다.
  2. WebSecurityConfig는 AuthenticationManager 의존성 주입을 받는다.
  3. AuthenticationManager는 Provider의 의존성 주입을 받는다.
  4. Provider는 PasswordEncoder의 의존성 주입을 받는다.

=> 4번에서 순환참조 발생!!

내가 해결한 방법

새로운 Config 클래스 만들어주기

PasswordEncoder를 다른 곳에 bean으로 등록해주면 해결이 되기 때문에 분리해주었다.

또 다른 방법?

https://ch4njun.tistory.com/269

  • @Lazy 어노테이션의 사용 (권장하지 않는다고 한다)
  • Setter 혹은 필드 주입 (이것도 권장하지 않는 방법!)
    https://programforlife.tistory.com/111#google_vignette
    - 필드 주입은 외부에서 수정이 불가해 테스트 코드를 못만든다.
    - Setter 주입은 객체 불변성을 보장하지 못한다.

결론 - 설계를 잘하자

처음부터 순환참조가 일어나지 않게 코드를 짜는 것이 가장 중요하다고 한다.
그러겠지...내가 못할 뿐

발생한 오류 2 - AuthenticationManager not must be specified

난 분명 AuthenticationManager에 의존성 주입까지 해줬는데 왜 안된다는거지? 했었다.

링크 - https://yoo11052.tistory.com/134


AbstractAuthenticationProcessingFilter.class

setAuthenticationManager
public void setAuthenticationManager(AuthenticationManager authenticationManager)

UsernamePassword머시기Filter를 지나 AbstractAuthenticationProcessingFilter 클래스를 보면 setAuthenticationManager()라는 메소드가 존재한다.

나는 주입만 해주고 아무것도 하지 않았던 것이었다...

해결

어차피 WebConfig에서 Filter를 생성하고 있었기에 의존성을 제거하고 Config클래스에서 모든 설정 값을 넣어주는 방식으로 수정했다.

public AuthenticationManager authenticationManager(){
CustomAuthenticationManager am = new CustomAuthenticationManager();

am.setAuthenticationProvider(provider);
//이 뒤에 핸들러도 등록하고 머도 등록하고... 그렇게 했다. 

필터 등록 관련해서도 여러 우여곡절이 있었는데 이건 다음 글에 작성하는걸로...

0개의 댓글