Spring Security 정복하기(4)

Spring Security Username/Password Authentication
이번 장에서는 아이디/비밀번호 기반 인증을 스프링 시큐리티가 어떻게 지원하는지 알아보자.

공식문서 첫번째 문단에서 Simple Username/Password 예시 코드를 제시한다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests((authorize) -> authorize
				.anyRequest().authenticated()
			)
			.httpBasic(Customizer.withDefaults())
			.formLogin(Customizer.withDefaults());

		return http.build();
	}

	@Bean
	public UserDetailsService userDetailsService() {
		UserDetails userDetails = User.withDefaultPasswordEncoder()
			.username("user")
			.password("password")
			.roles("USER")
			.build();

		return new InMemoryUserDetailsManager(userDetails);
	}

}
  • InMemoryUserDetailsService를 빈으로 등록한다.
  • AuthenticationManager에 DaoAuthenticationProvider를 등록하고, 폼로그인과 HTTP 기본인증을 활성화한다.

인메모리유저디테일즈서비스

  • InMemoryUserDetailsService는 내부적으로 Map으로 사용자를 관리한다.
  • UserDetailsManager의 상속관계를 따라 올라가다보면 최상위 부모는 UserDetailsService이다.
  • UserDetailsService를 구성하면 스프링 시큐리티는 자동으로 DaoAuthenticationProvider를 사용하여 인증처리를 진행한다.

DaoAuthenticationProvider

DaoAuthenticationProvider : UserDetailsService와 PasswordEncoder를 사용하여 사용자 이름과 비밀번호를 인증하는 AuthenticationProvider 구현이다.
아래 그림은 공식문서의 그림이다. dao

  1. 인증 필터는 ProviderManager에서 구현한 AuthenticationManager에 UsernamePasswordAuthenticationToken을 전달한다.
  2. ProviderManager는 DaoAuthenticationProvider 유형의 AuthenticationProvider를 사용하도록 구성된다.
  3. DaoAuthenticationProvider는 UserDetailsService에서 UserDetails를 조회한다.
  4. DaoAuthenticationProvider는 PasswordEncoder를 사용하여 이전 단계에서 반환된 UserDetails에서 비밀번호를 검증한다.
  5. 인증이 성공하면 반환되는 인증은 UsernamePasswordAuthenticationToken 유형이고 UserDetailsService에서 반환된 UserDetails가 토큰에 포함된다. 궁극적으로 반환된 UsernamePasswordAuthenticationToken은 인증 필터에서 SecurityContextHolder에 설정된다.