SecurityContextHolder, SecurityContext, Authentication

  1. SecurityContextHolder : 보안 정보를 보관하는 금고

    1. 현재 실행 중인 스레드(보통 하나의 웹 요청을 처리하는 스레드)와 관련된 '보안 문맥(SecurityContext)'를 담아두는 역할을 한다.

    2. Controller,Service, View 모든 곳에서 현재 요청을 보낸 사용자의 보안 정보(누군지, 권한이 무엇인지 등)에 쉽게 접근할 수 있다. SecurityContextHolder.getContext() 메소드를 호출하면 현재 스레드의 SecurityContext를 꺼낼 수 있다.

    3. 기본적으로 ThreadLocal을 사용해 각 스레드마다 독립적인 SecurityContext를 보관한다.

  2. SecurityContext : 실제 보안 정보가 담긴 서류철/문서

    1. 현재 인증된 사용자의 인증 정보 객체(Authentication)을 담고 있다.

  3. Authentication: 사용자의 '신분증과 권한 목록' 객체

    1. 이 녀석은 현재 시스템을 사용하려는 '주체(Principal)' 에 대한 정보와 그 주체가 가지고 있는 '권한(Authorities)' 정보를 담고 있는 가장 구체적인 객체이다.

      1. Principal: 주체를 나타낸다. 보통 UserDetailsService에서 로드된 UserDetails 객체나 단순히 사용자 이름(String)일 수 있다.

      2. Credentials: 주체의 신원을 증명하는 정보. 비밀번호나 토큰 등이 담긴다.

      3. Authorities : 주체가 가지고 있는 권한 (Roles 또는 Permission)

      4. Details : 요청에 대한 추가 정보(예: IP 주소, 세션 ID)

      5. isAuthenticated() : 객체가 인증이 완료된 유효한 객체인지 아닌지 나타내는 boolena 값을 반환한다.

간단 흐름 👍

  1. 클라이언트 요청 : 사용자가 웹 요청을 보냄

  2. 스프링 시큐리티 필터 체인 : 요청이 스프링 시큐리티 필터들을 통과한다.

  3. 인증 필터 : UsernamePasswordAuthenticationFilter 같은 인증 관련 필터가 요청에서 사용자 정보(아이디, 비밀번호 등)을 추출해 아직 인증되지 않은 Authentication 객체를 만든다.

  4. AuthenticationManager : 인증되지 않은 Authentication 객체를 AuthenticationManager에게 넘겨 인증을 시도

  5. AuthenticationProvider : AuthenticationManager는 적절한 AuthenticationProvider를 찾아서 실제 인증 로직을 수행한다.

  6. 인증이 성공하면 isAuthenticated()가 true로 설정된 새로운 Authentication 객체를 만들어서 반환한다.

  7. SecurityContext 생성 및 설정: 인증 필터는 성공적으로 반환받은 인증된 Authentication 객체를 가지고 SecurityContext 객체를 만들고, 이 SecurityContextSecurityContextHolder에게 넘겨서 현재 스레드에 보관하게 해!

  8. 이후 요청 처리: 이제 요청이 나머지 필터들이나 DispatcherServlet, Controller 등으로 전달될 때, 언제든 SecurityContextHolder.getContext().getAuthentication() 코드를 통해 현재 사용자가 누구이고 어떤 권한이 있는지 확인하고 이를 기반으로 접근 제어(@PreAuthorize 등)를 수행할 수 있게 된다!

Last updated