Spring Security Authentication Architecture (feat. 6.2.2ver)

Authentication Archtecture 

SecurityContextHolder: 인증된 유저의 상세 정보가 저장된 스프링 시큐리티의 영역

  • ThreadLocal(스레드 단위로 할당 가능한 변수)을 사용하여 정보를 저장하여, SecurityContext가 요청을 처리하는 메서드의 파라미터로 들어가지 않더라도 항상 같은 스레드에서 사용할 수 있다.
  • 현재 인증 요청을 처리한 뒤 스레드를 삭제하면 ThreadLocal은 안전한 방법이며, FilterChainProxy를 사용하면 SecurityContext가 항상 지워진다.

SecurityContext: 현재 인증된 유저의 인증 정보(Authentication)를 포함하며, SecurityContextHolder로부터 가져올 수 있다.

//Sample Code
SecurityContext context = SecurityContextHolder.createEmptyContext(); 
Authentication authentication =
    new TestingAuthenticationToken("username", "password", "ROLE_USER"); 
context.setAuthentication(authentication);

SecurityContextHolder.setContext(context);
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();
Object principal = authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

 

Authentication: SecurityContext로부터 현재 유저 또는 유저가 인증을 위해 제공한 자격 증명(토큰, 세션아이디, 아이디, 비번 .. 등)을 제공하기 위해 AuthenticationManager에 입력할 수 있다.  인증 내용은 아래 3가지이다.

  • 유저가 제공한 자격 증명을 AuthenticationManager에 입력하고, ScurityContext에서 Authentication을 얻을 수 있다.
  • principal: UserDetails의 구현체로 username, password로 인증할 때 사용하여 사용자를 식별한다.
  • credentials: 암호이며, 사용자가 인증되면 유출되지 않도록 지워진다.
  • authorities: 허가된 역할과 범위를 가진 권한(GrantedAuthority)

 

GrantedAuthority: 인증 주체에게 부여된 권한 (관리자, 유저 등)

  • username/password 기반 인증에서 권한은 UserDetailsService에 의해 로드된다.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

 

 

AuthenticationManager: 스프링 시큐리티 필터가 인증을 수행하는 방법을 정의하는 API 

  • Authentication를 파라미터로 받는 authenticate() 메서드를 가지고 있다.

ProviderManager: AuthenticationManager의 가장 일반적인 구현체

  • (AuthenticationManager는 ProviderManager에게 인증을 위임하여, 다양한 구현체를 활용할 수 있도록 다형성을 살림)

AuthenticationProvider: ProviderManager가 특정한 유형의 인증을 수행하기 위해 사용된다.

 

 

 

Request Credentials with AuthenticationEntryPoint: 인증 진입점으로 자격 증명 요청이라는 뜻으로 클라이언트에게 자격증명을 요청하는 응답을 보내는데 사용하며, 아래는 사용 예시이다.

  • 로그인 페이지로 리다이렉션
  • WWW-Authenticate 응답 : 서버에서 사용자에게 인증 정보를 제공하라는 401 Unauthorized 요청과 함께 요청을 반려하는 응답

AbstractAuthenticationProcessingFilter: 인증에 사용되는 기본 필터로 추상클래스이기 때문에 구현체를 사용해야한다.

  1. AbstractAuthenticationProcessingFilter는 HttpServletRequest에서 인증을 생성하게 되는데 생성된 인증의 유형은 filter의 하위 클래스(구현체)에 따라 다르다.
  2. UsernamePasswordAuthenticationFilter를 사용했다면, UsernamePasswordAuthenticationToken이 생성된다.
  3. 아래 그램에서 UsernamePasswordAuthenticationToken이 Authentication이며, AuthenticationManager -> ProviedManager -> AuthenticationProvider에서 인증이 진행된다.
  4. 이때 인증에 실패하면 AuthenticationFailureHandler에서 SecurityContextHolder가 지워지게된다.
  5. 인증에 성공하면 SessionAuthenticationStrategy에서 새로운 로그인을 알리고, SecurityContextHolder에 저장된다.