Storage Mechanisms
Username과 Password를 읽기 위해 제공되는 저장 기술들(UserDetailsService의 구현체)은 아래와 같다.
- In-Memory Authentication
- JDBC Authentication (JDBC를 사용하는 경우)
- UserDetailsService (커스텀 데이터 베이스를 사용하는 경우)
- LDAP Authentication (LDAP 저장소를 사용하는 경우)
UserDetailsService
저장 기술들의 종류로 해당 인터페이스를 구현한 클래스들을 사용하여
UserDetails의 관리를 제공하고 인증을 할 수 있게 한다.
(기본적으로 인메모리 방식과 JDBC 방식을 지원한다.)
이를 사용한 인증 방식은 Username과 Password를 사용하는 인증 방식 사용 시
스프링 시큐리티에서 기본적으로 사용하게 설정된다.
@Bean
CustomUserDetailsService customUserDetailsService() {
return new CustomUserDetailsService();
}
위와 같이 UserDetailsService를 직접 커스텀하여 빈으로 등록하여 사용할 수도 있다.
UserDetails
UserDetailsManager를 통해 얻을 수 있는 객체로
DaoAuthenticationProvider가 UserDetails가 유효한지 확인한 후에
UserDetailsManager로 부터 인증된 UserDetails를 반환한다.
즉, user라는 Username을 가진 UserDetails가 있는지 확인한 후에
password까지 일치한다면 인증이 추가된 UserDetails를 반환한다.
PasswordEncoder
인코더라는 단어에서 알 수 있듯이 패스워드를 암호화하여 저장할 수 있는 기능을 지원한다.
PasswordEncoder도 마찬가지로 커스텀 구현하여 빈으로 등록하여 사용할 수 있다.
DaoAuthenticationProvider
위에서 알아본대로 UserDetailsService와 PasswordEncoder를 사용하여
Username 및 Password 기반의 인증을 수행하는 AuthenticationProvider의 구현 클래스다.
인증 과정을 순서대로 살펴보자면 아래와 같다.
- 아직 인증되지 않은 UsernamePasswordAuthenticationToken(토큰이라고 부르겠음)을 DaoAuthenticationProvider로 전달한다.
- 해당 토큰의 정보로 UserDetailsService에서 UserDetails를 조회한다.
- 그 후 PasswordEncoder를 사용하여 UserDetails의 패스워드와 토큰의 패스워드를 검증한다.
- 인증에 성공하면 인증이 추가된 토큰을 반환한다.
- 이는 최종적으로 필터에 의해 SecurityContextHolder에 저장된다.
In-Memory Authentication
InMemoryUserDetailsManager를 사용하는 인증 방식이다.
@Bean
public UserDetailsService users() {
//User의 UserDetails 생성
UserDetails user = User.builder()
.username("user")
.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER")
.build();
//Admin의 UserDetails 생성
UserDetails admin = User.builder()
.username("admin")
.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
.roles("USER", "ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
위의 코드처럼 username, password, role을 지정하여 UserDetails를 생성한 후에
이를 사용해 InMemoryUserDetailsManager 객체를 생성한다.
어디서 많이 본거 같은 익숙한 느낌이 들 수도 있는데
이는 스프링 시큐리티의 기본 로그인 페이지에 접속할 때 사용하던
접속 정보를 생성해주던 코드이다.
즉, 서버 실행 시 콘솔창에 출력된 랜덤 비밀번호와 user라고 입력해서 로그인을 하면
해당 정보를 가지고 위의 InMemoryUserDetailsManager를 사용해
해당 정보와 일치하는 UserDetails가 있는지 확인하여 로그인이 되던 것이다.
하지만 인메모리 저장소의 휘발성이라는 특성 때문에
개발 및 테스트 단계에서만 사용하는 것을 권장하고 실제 배포 단계에서는 사용하면 안된다.
'Back-End > Security' 카테고리의 다른 글
JWT 로컬 로그인 구현하기 - 2편 (0) | 2023.09.23 |
---|---|
JWT 로컬 로그인 구현하기 - 1편 (0) | 2023.09.21 |
[스프링 시큐리티] 공식문서로 배워보기 : Username/Password - 1 (0) | 2023.08.14 |
[스프링 시큐리티] 공식문서로 배워보기 : 인증 아키텍처 (0) | 2023.08.14 |
[스프링 시큐리티] 공식문서로 배워보기 : 의존성 추가 (0) | 2023.08.11 |