![Spring Security Authentication Architecture (feat. 6.2.2ver)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqXVKD%2FbtsE7ugmz08%2FVcEtuEUh9xxohFKKPjfJF1%2Fimg.png)
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: 인증에 사용되는 기본 필터로 추상클래스이기 때문에 구현체를 사용해야한다.
- AbstractAuthenticationProcessingFilter는 HttpServletRequest에서 인증을 생성하게 되는데 생성된 인증의 유형은 filter의 하위 클래스(구현체)에 따라 다르다.
- UsernamePasswordAuthenticationFilter를 사용했다면, UsernamePasswordAuthenticationToken이 생성된다.
- 아래 그램에서 UsernamePasswordAuthenticationToken이 Authentication이며, AuthenticationManager -> ProviedManager -> AuthenticationProvider에서 인증이 진행된다.
- 이때 인증에 실패하면 AuthenticationFailureHandler에서 SecurityContextHolder가 지워지게된다.
- 인증에 성공하면 SessionAuthenticationStrategy에서 새로운 로그인을 알리고, SecurityContextHolder에 저장된다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!