Spring/Spring Security

[Spring Security] 3-2. 인증: 아이디 / 패스워드

noahkim_ 2023. 10. 2. 16:37

1. 인증 정보 습득방식

  • Spring Security는 기본적으로 클라이언트로부터 인증 정보를 얻기 위한 세가지 방법을 지원합니다. 
  • 기본 인증 방식은 HttpServletRequest 객체로부터 아이디 패스워드 정보를 얻습니다.

Form

Basic

Digest

 

2. 비밀번호 저장소 (Password Storage)

UserDetails

  • UserDetails는 Spring Security에서 유저의 정보를 나타내는 인터페이스입니다.
  • 사용자가 로그인 요청을 할 경우, DaoAuthenticationProvider는 UserDetailsService를 통해 사용자의 정보를 조회합니다.
    • UserDetailsService에 의해 UserDetails 인터페이스의 구현체가 반환됩니다.
    • UserDetails 구현체의 필드 정보를 가지고 입력받은 패스워드와 저장된 패스워드를 비교하여 인증을 시도합니다.
    • 인증에 성공하면 인증된 사용자 정보를 사용하여 Authentication을 생성하여 반환합니다.

 

UserDetailsService

  • UserDetailsService는 유저의 정보를 조회하는데 사용되는 인터페이스입니다.
  • DaoAuthenticationProvider에서 인증을 시도할 때, 유저의 정보를 가져오기 위해 주로 사용됩니다.
  • Spring Security는 기본적으로 InMemoryUserDetailsManager, JdbcDaoImpl 구현체를 지원합니다.
  • 또한 사용자가 커스터마이징하여 빈으로 등록할 수 있습니다.

 

In Memory

  • In Memory 기반의 유저 인증을 관리하는 객체인 InMemoryUserDetailsManager를 지원합니다. 
  • InMemoryUserDetailsManager는 UserDetailsManager 인터페이스의 구현체입니다.
    • UserDetailsManager 인터페이스는 UserDetails 생성 및 제거 등의 조작을 담당합니다.
    • UserDetailsManager 인터페이스는 UserDetailsService를 확장합니다.

 

JDBC

  • JdbcDaoImpl 객체는 아이디 / 패스워드 방식의 인증을 지원합니다.
    • JdbcDaoImpl는 UserDetailsService 인터페이스의 구현체입니다.
    • JdbcDaoImpl은 테이블로부터 유저의 정보를 가져오도록 설계되어있습니다. 
      • 기본적으로 User와 Group이라는 테이블에서 JDBC 기반 기술을 사용하여 인증객체를 가져옵니다.
      • org/springframework/security/core/userdetails/jdbc/users.ddl 에 기본 스키마 파일이 제공됩니다.
  • JdbcUserDetailsManager 객체는 UserDetailsManager 인터페이스의 구현체입니다.
    • UserDetailsManager 인터페이스는 UserDetails 생성 및 제거 등의 조작을 담당합니다.
    • JdbcUserDetailsManager는 JdbcDaoImpl를 확장합니다.

 

User 스키마

create table users(
    username varchar_ignorecase(50) not null primary key,
    password varchar_ignorecase(500) not null,
    enabled boolean not null
);

create table authorities (
    username varchar_ignorecase(50) not null,
    authority varchar_ignorecase(50) not null,
    constraint fk_authorities_users foreign key(username) references users(username)
);

create unique index ix_auth_username on authorities (username,authority);

 

 

Group 스키마

create table groups (
    id bigint generated by default as identity(start with 0) primary key,
    group_name varchar_ignorecase(50) not null
);

create table group_authorities (
    group_id bigint not null,
    authority varchar(50) not null,
    constraint fk_group_authorities_group foreign key(group_id) references groups(id)
);

create table group_members (
    id bigint generated by default as identity(start with 0) primary key,
    username varchar(50) not null,
    group_id bigint not null,
    constraint fk_group_members_group foreign key(group_id) references groups(id)
);

 

PasswordEncoder

  • Spring Security는 PasswordEncoder라는 객체를 사용하여 안전하게 비밀번호를 저장합니다.
  • 사용자는 빈으로 등록하여 PasswordEncoder 객체를 커스터마이징할 수 있습니다. 

 

DaoAuthenticationProvider

  • DaoAuthenticationProvider는 AuthenticationProvider 인터페이스의 구현체입니다.
  • DaoAuthenticationProvider는 입력 username, password를 UserDetailsService, PasswordEncoder로 인증을 시도합니다.
    • 인증 필터에서 입력 username, password을 AuthenticationToken 형식으로 전달합니다.

 

  1. 인증 필터에서 입력 username, password을 UsernamePasswordAuthenticationToken 형식으로 AuthenticationManager에게 전달합니다.
  2. ProviderManager는 DaoAuthenticationProvider를 사용하도록 설정되어 있습니다.
  3. DaoAuthenticationProvider는 UserDetailsService를 사용하여 UserDetails를 조회합니다.
  4. DaoAuthenticationProvider는 PasswordEncoder를 사용하여 조회된 UserDetails의 패스워드의 유효성을 검증합니다.
  5. 검증에 성공하면, UsernamePasswordAuthenticationToken 형식의 Authentication 객체를 리턴합니다.

 

 

 

참고