스프링 시큐리티의 filter를 이용하여
로그인기능을 구현하던 중 authenticationManager must be specified 이라는 에러에 막혔다.
아직도 많은 예제가 SpringBoot 3.0부터는 완전히 deprecated된 WebSecurityConfigurerAdapter를 구현하고 있었기 때문에
적당한 예제를 찾기가 힘들었고,
단순히 AuthenticationManger를 못 찾는건지
FilterChain 메소드를 잘못 작성하고 있는건지 고민하면서 많은 시간을 보냈다.
커스텀한 필터가 상속받고 있는 클래스인
AbstractAuthenticationProcessingFilter 클래스에 AuthenticationManager 객체가 기본적으로 할당되지 않기 때문에 발생한 에러이다.
* 스프링시큐리티가 적당히 잘 해주겠지.. 하고 생각하다가
SecurityConfig
// 1번
@Bean
public AuthenticationManager authenticationManager() throws Exception{
return this.authenticationConfiguration.getAuthenticationManager();
}
// 2번
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(c -> c.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.antMatchers("/**").authenticated()
)
.authenticationProvider(authenticationProvider)
.addFilter(customAuthenticationFilter())
.build();
}
// 3번
@Bean
public AuthenticationFilter customAuthenticationFilter() throws Exception {
AuthenticationFilter filter = new AuthenticationFilter();
filter.setAuthenticationManager(authenticationManager());
return filter;
}
1. 3번부분. 맨 아래부분 필터를 Bean 객체로 등록해줄 때 AuthenticationManager를 등록해준다.
2. 예제버전 SpringBoot2.7.17 버전에선 authenticationManager() 라는 메소드가 기본적으로 제공이 되지 않는다.
-> 1번부분. AuthenticationManager 객체를 bean으로 등록해서 사용
3. .addFilter(customAuthenticationFilter()) 를 통해 설정한 정보를 주입한다.
4. [주의!!!] 커스텀한 필터 객체의 클래스 레벨에 @Component와 같은 애노테이션을 달지 않는다.(Config파일에서 의존성 주입을 하므로)