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 구현이다.
아래 그림은 공식문서의 그림이다.

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