AuthenticationManager

황상익·2024년 9월 19일

security

목록 보기
7/16

1. AuthenticationManager

인증 필터로 부터 Authentication 객체를 전달받아 인증을 시도, 성공시 → 사용자 정보 권한등을 포함한 완전히 채워진 Authentication 객체를 반환 (인증 받기 전과 인증 받은 후 다리 역할)
AuthenticationManager는 여러 AuthenticationProvider 관리 → AuthenticationProvider 목록을 순차적 조회, 인증 요청을 처리
AuthenticationProvider 목록 중 인증 처리 요건에 맞는 적절한 AuthenticationProvider를 찾아 인증 처리를 위임 (인증 받을 값을 다시 필터에 넘겨줌 → AuthenticationManager 역할)
AuthenticationManagerBuilder에 의해 객체가 생성, 주로 사용하는 구현체는 ProviderManager 제공
ProviderManager → 적합한 Provider를 몰색해서 처리 → (즉 중간 다리 역할만 하는 것)

ProviderManager가 갖고 있는 Authentication이 없다면 → 인증 실패 처리
⇒ AuthenticationProvider 로 부터 null 이 아닌 응답을 받을 때 까지 차례대로 시도하며 응답을 받지 못하면 ProviderNotFoundException과 함께 인증이 실패

  1. AuthenticationManagerBuilder
    AuthenticationManager 객체를 생성하며, UserDetailService 및 AuthenticationProvider를 추가
    HttpSecurity.getSharedObject를 통해 객체를 참조
    (AuthenticationManager → AuthenticationProvider를 따로 추가 할 수 있는 기능 x, 따라서 build를 통해 생성)

3. AuthenticationManager 사용법 → HttpSecurity 사용 (SecurityBuilder 중 하나이다.)

@Bean

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);

AuthenticationManager authenticationManager = authenticationManagerBuilder.build();
AuthenticationManager authenticationManager = authenticationManagerBuilder.getObject();

http
.authorizeHttpRequests(auth -> auth

.requestMatchers("/api/login").permitAll()

// build() 는 최초 한번 만 호출해야 한다 (생성시)
// build() 후에는 getObject() 로 참조해야 한다 (가져올때) 

.anyRequest().authenticated())
.authenticationManager(authenticationManager) // HttpSecurity 에 생성한 AuthenticationManager 를 저장한다
.addFilterBefore(customFilter(http, authenticationManager), // 객체를 사용  UsernamePasswordAuthenticationFilter.class);

return http.build();
}

// @Bean 으로 선언하면 안된다. AuthenticationManager 는 빈이 아니기 때문에 주입받지 못한다

public CustomAuthenticationFilter customFilter(AuthenticationManager authenticationManager) throws Exception {

CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter();
customAuthenticationFilter.setAuthenticationManager(authenticationManager);
return customAuthenticationFilter;

}

4. AuthenticationManager 직접 생성

//여기서는 아무런 작업을 하지 않는다.

@Bean

public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
http.formLogin(Customizer.withDefaults());
http.addFilterBefore(customFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();

}
@Bean // @Bean 으로 선언이 가능하다
public CustomAuthenticationFilter customFilter(){

List<AuthenticationProvider> list1 = List.of(new DaoAuthenticationProvider());
ProviderManager parent = new ProviderManager(list1); //list 타입의 객체로 넘길 수 있다. 
List<AuthenticationProvider> list2 = List.of(new AnonymousAuthenticationProvider("key"), new CustomAuthenticationProvider()); // 자신도 있지만 부모 역할의 parent ProviderManger  객체를 줄 수 있다. 
ProviderManager authenticationManager = new ProviderManager(list2,parent);

CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter();
customAuthenticationFilter.setAuthenticationManager(authenticationManager);

return customAuthenticationFilter;
}
profile
개발자를 향해 가는 중입니다~! 항상 겸손

0개의 댓글