Spring/Spring Security

Spring Security (3) - Authentication

Authentication 은 인증정보(Principal) 를 가지는 객체로 실제로 유효한 인증인지를 나타냅니다.

  • 인증이 완료되기 전에는 사용자가 입력한 인증에 필요한 정보(username, password 등)를 가지고 있는 객체
  • 인증이 완료되면, 인증 정보를 담는 객체

인증과정

  • 인증되지 않은(로그인하지 않은) 상태에서 url 에 접근할 경우, AnonymousAuthenticationFilter 가 AnonymousAuthenticationToken(Authentication - 익명사용자를 나타내는 정보가 들어있음) 을 SecurityContextHolder 에 넣어줍니다.

  • 인증을 요청하면 (로그인 요청) UsernamePasswordAuthenticationFilter (form login 시 인증을 담당하는 기본 구현체) 에서 UsernamePasswordAuthenticationToken(Authentication - 인증된 정보) 을 반환하게 됩니다.

  • UsernamePasswordAuthenticationFilter 는 AuthenticationManager 를 통해 인증을 처리
  • AuthenticationManager 는 기본적으로 ProviderManager 를 구현체로 사용
  • ProviderManager 의 authenticate 메서드 안에서 AuthenticationProvider 를 호출하여 인증을 처리
    • 기본 구현체로(form 인증) DaoAuthenticationProvider 를 사용
    • ProviderManager 는 provider 의 authenticate 메서드를 호출
      • AbstractUserDetailsAuthenticationProvider.authenticate 메서드가 실행되어 템플릿 메서드 패턴으로 DaoAuthenticationProvider.retrieveUser 를 호출
        => UserDetails 에 구현된 loadUserByUsername 을 호출, UserDetails type 의 클래스를 반환
        => UserDetails 를 구현하는 클래스에서 loadUserByUsername 메서드를 오버라이딩 함으로써 원하는 커스텀 유저 클래스를 구현

설정

  • form login 기본 설정

    @Configuration
    @EnableWebSecurity
    @RequiredArgsConstructor
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http.formLogin()          //form login 사용
          .loginPage("/login")  //로그인 page url 지정
          .permitAll();         //모든 사용자가 접근가능
    }
    }
  • form login 이 아닌 token 등을 이용하는 설정

    @Configuration
    @EnableWebSecurity
    @RequiredArgsConstructor
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
      http
          .cors().disable()
          .csrf().disable()
          .formLogin().disable()
          .headers().frameOptions().disable()
          .and()
          .addFilter(filter)    //커스텀 필터 추가(필터 구현해야 함)
          .sessionManagement()  //세션을 사용하지 않음
          .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
    }

정리

AuthenticationManager

  • 실제로 인증을 담당
    • ProviderManager : 기본 구현체
      • DaoAuthenticationProvider : form 인증일 경우 기본 구현체이며, UsernamePasswordAuthenticationToken 을 생성
      • 실제로는 ProviderManager 안에 인증을 처리할 provider list 가 있고, 그 중 실제 처리를 할 provider 를 찾음
    • 인증을 거쳐 UserDetailService.loadUserByUsername 에서 반환하는 객체를 가져옴(커스텀하게 구현 가능)

Authentication

  • Principal : 인증정보, UserDetailsService 구현체에서 반환하는 UserDEtails 타입의 객체 :: 기본 구현일 경우이고, 검증 필터를 커스텀하게 구현하여 유저가 원하는 형태의 객체를 principal로 사용 가능
  • GrantAutority : ROLE_USER 와 같이 Principal 이 가지는 권한을 나타냄