Spring Securityの完全なプロセスの表示


Spring Securityの詳細


Spring Security에 대해서 간략히 알아보자.

Spring Securityの流れについて

Spring Security를 dependencies에 추가하게 되면 해당 어플리케이션을 실행시켰을 때 해당
앱으로 오는 모든 request는 Spring Security가 잡아채게 된다.

(1) 사용자가 아이디와 비번을 치면 해당 아이디와 비번은 (2)Authentication 객체로 들어가게된다. 
일단 Authentication 객체가 만들어지게 되면 그 다음의 흐름은 (3)Authentication Manager가 관
장한다.

후의 과정은 차차 업데이트 하기로... 개략적인 부분은 차차 업데이트 하기로 하겠다.

AuthenticationFilter

Authentication

Authentication Manager

Authentication Provider


UserDetailsManager

이번에는 사용자와 관련한 CRUD를 메서드를 갖고 있는 인터페이스인 UserDetailsManager에 대해서 알아보자.

아래 그림은 interface UserDetailsManager가 어떻게 구성되어 있는지 보여주는 그림이다. 메소드를 살펴보면
사용자를 CRUD 하는 함수들이 들어있고 매개변수로 UserDetails라는 객체가 들어가 있는 것을 확인할 수 있다. 즉
사용자를 생성, 업데이트, 삭제, 비밀번호 변경, 유저유무 확인 등을 할 때 UserDetailsManager를 상속받아서 사
용하겠구나 라는 사실을 알 수 있다.

UserDetailsService

UserDetailService는 interface이다. 해당 인터페이스는 하나의 함수만을 가지고 로그인할 때 입력하는
사용자의 이름을 매개변수로 받는다.

해당 인터페이스는 DAO(Data Access Object)의 객체로서의 역할을 하고 UserDetails 객체를 반환한다.

해당 객체는 사용자의 인증과 인가에 대한 정보를 담고 있다.

DaoAuthenticationProvider가 해당 정보를 갖고 유저에 대한 인증과 인가에 대한 내용을 처리한다.
아래의 코드는 UserDetailService 안에 있는 loadUserByUsername을 Override 하는 방법에 대한 예시이다.

    @Override
    public UserDetails loadUserByUsername(String username) 
    throws UsernameNotFoundException {
        final CustomerEntity customer = customerRepository.findByEmail(username);
        if (customer == null) {
            throw new UsernameNotFoundException(username);
        }
        UserDetails user = User.withUsername(customer.getEmail())
        .password(customer.getPassword())
        .authorities("USER").build();
        return user;
    }
코드에 대한 이해를 돕자면  User <- UserDetails <- UserDetailsService 순서로 UserUserDetailsUserDetailsService을 상속 받고 있다.

1. 코드를 살펴보면 이메일이 고유한 키로서 작용한다는 것을 전제하에 customer라는 Entity 객체를 찾는다.

2. User라는 class가 있는데 해당 classwithUsername()이라는 함수를 static 으로 갖고 있어서 User
   class만 포함시켜서 바로 User. ~ 형태로 사용할 수 있다.

3. withUsername()이라는 함수는 반환값으로 UserBuilder(객체)를 반환한다. 기능으론 UserBuilder 
   객체 내부에 있는 변수 username에 withUsername(String param) 의 매개변수로 들어온 값을 할당한다.
   
   다시 정리하자면 해당 코드 User.withUsername(customer.getEmail()) 에 대한 설명이 2, 3 번에 해당
   하는 것인데 customer 안의 이메일 값을 매개변수로 넣어서 User 객체 내부의 username에 해당 값을 넣어
   준 것이고 UserBuilder 객체를 반환하여 다시 UserBuilder 내부의 password(), authorities() 함수들,
   withUsername과 같은 방식으로 동작하는 로직을 적용시킴으로써 User 내부의 변수에 값을 할당해 준 것이다.
   
   마지막의 build() 함수의 경우 UserDetails로 type을 casting 해주는 역할을 한다.
User라는 class가 static 함수로 갖고 있는 withUsername, 매개 변수로 PK 기능을 하는 매개변수를 받
는다.
public static final class User.UserBuilder 내부에 선언된 메서드 username(String username)이다.
위의 과정이 loadUserByUsername을 매개변수로 UserDetails를 반환하는 메소드를 오버라이딩한 예시에 대한
해석이다.

UserDetails

UserDetails 인터페이스는 아래와 같은 함수들을 갖고 있다. 함수 내용만 보면 계정에 대한 인증을 담당하는 
함수들과 패스워드와 유저이름을 갖고 오는 함수로 구성되어 있다는 것을 볼 수 있다.

詳細ユーザー詳細サービスについて

PasswordEncoder

Security Context