728x90

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의 구현 클래스다.

 

 

인증 과정을 순서대로 살펴보자면 아래와 같다.

  1. 아직 인증되지 않은 UsernamePasswordAuthenticationToken(토큰이라고 부르겠음)을 DaoAuthenticationProvider로 전달한다.
  2. 해당 토큰의 정보로 UserDetailsService에서 UserDetails를 조회한다.
  3. 그 후 PasswordEncoder를 사용하여 UserDetails의 패스워드와 토큰의 패스워드를 검증한다.
  4. 인증에 성공하면 인증이 추가된 토큰을 반환한다.
  5. 이는 최종적으로 필터에 의해 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가 있는지 확인하여 로그인이 되던 것이다.

 

하지만 인메모리 저장소의 휘발성이라는 특성 때문에

개발 및 테스트 단계에서만 사용하는 것을 권장하고 실제 배포 단계에서는 사용하면 안된다.

+ Recent posts