본문 바로가기
spring/security

SecurityContext 와 Authentication 내부 속으로

by 참된오징어 2021. 5. 17.

이전 포스팅에서는 SecurityContext를 가지고 있는 SecurityContextHolder 내부를 살펴보았다.

이번에는 SecurityContext와 Authentication의 내부를 살펴보자.

 

 

 

# SecurityContext


javadoc에 설명된 내용을 해석해보자.

 

현재 실행 중인 쓰레드와 연관된 최소한의 보안 정보를 정의하는 인터페이스이다.

SecurityContext는 SecurityContextHolder에 저장된다.

 

SecurityContext를 구현한 구현체는 SecurityContextImpl 하나밖에 없다.

(SecurityContextImpl 내부를 보면 Authentication을 가지고 있는 것 외에는 크게 중요한 게 없다.)

 

다음으로 Authentication 내부를 살펴보자.

 

 

 

 

# Authentication


javadoc을 읽어보자.

 

토큰을 표현하는 것인데, 어떤 토큰이냐면 인증 요청에 대한 토큰 혹은

AuthenticationManager.authenticate (Authentication) 메서드에 의해

요청이 처리 된 후 인증된 Principal에 대한 토큰이다.

 

요청이 인증되면, 그 인증은 보통 사용 중인 인증 메커니즘에 의해 SecurityContextHolder에 저장되고

SecurityContextHolder에 의해 관리되는 SecurityContext Thread-Local에 저장이 된다.

스프링 시큐리티의 인증 메커니즘 중 하나를 사용하지 않고 Authentication 인스턴스를 만들고 다음과 같은 코드를 사용하면

명시적인 인증을 수행할 수 있다. 

 

SecurityContextHolder.getContext().setAuthentication(anAuthentication);

 

Authentication이 가지고 있는 authenticated 속성이 true로 설정되어 있지 않으면

발견될 때마다 계속 인증될 것이다 모든 시큐리티 인터셉터에 의해 (메서드 또는 웹 호출의 경우)

 

대부분의 경우, 프레임 워크는 시큐리티 컨텍스트 및 인증 개체를 투명하게 관리한다 당신을 위해

 

즉, Authentication은 인증 정보를 가지는 인터페이스인데
해당 인증 정보가 인증 요청일 수도 있고 인증된 결과일 수 있다는 것이다.
그리고 authenticated() 메서드를 통해 인증되었는지 안되었는지 확인할 수 있다.

 

다음에 알아볼 AuthentatcationManager는 실제로 인증을 처리하는 역할을 가진 인터페이스인데

추상 메서드를 살펴보면 둘 다 Authentication을 파라미터로 받고 Authentication을 반환해주고 있다.

파라미터로 인증이 필요한 요청의 정보일 것이고, Authentication은 인증된 정보일 것으로 추측이 가능하다.

 

 

 

다음으로 Authentication에 선언된 추상 메서드들을 알아보자.

 

Collection<? extends GrantedAuthority> getAuthorities();

- 인증된 주체인 Principal이 가지고 있는 권한들이다. AuthenticationManager에 의해 set 된다.

 

Object getCredentials();

- 인증된 주체인 Principal의 정확함을 증명하는 값. 

- 일반적으로 암호이지만 Authentication과 관련된 모든 것이 될 수 있다.

- 인증이 완료되면 Credentials 데이터를 제거한다. (인증이 되었기에 서버에서 계속 가지고 있을 필요가 없음)

 

Object getDetails();

- 추가적으로 세부 사항을 저장할 수 있는 정보이다. IP 주소, 인증서 시리얼 넘버 같은 값 등일 수 있다.

 

Object getPrincipal();

- 인증된 주체의 식별자, 인증 정보를 가지고 있다.

- 많은 인증 프로바이더들은 UserDetails 객체로 반환을 한다.

 

boolean isAuthenticated();

- 인증되었는지 안되었는지 확인하는 메서드

 

void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;

- boolean 파라미터를 통해 인증 정보를 신뢰할 수 있는지 아닌지 set 해주는 메서드

- 토큰을 신뢰해야 하는 경우 true를 파라미터로 전달한다. (이때 내부에서 예외가 발생할 수 있다.)

- 토큰을 항상 신뢰하지 않아야 하는 경우 false를 파라미터로 전달한다.

 

Authentication의 구현체들은 다음과 같다.

 

구현체들은 대부분 ~~~ Token이라는 네이밍을 하고 있다..!

그리고 우리가 자주 사용하는 구현체는 아무래도 UsernamePasswordAuthenticationToken이지 않을까 한다.

해당 구현체 내부도 간단하게 되어있다. 인스턴스로 principal과 credentials를 가지고 있고

비밀번호를 지울 수 있는 메서드를 가지고 있다.

 

 


이번 포스팅을 통해 SecurityContext와 Authentication의 역할과 내부를 파악하였다.

인증된 정보들은 Authentication을 생성하고, SecurityContext에 보관이 된다.

그리고 SecurityContext는 쓰레드에 어떻게 공유될지 모르기에 Authentication을 관리하는 생명주기이며

SecurityContextHolder에 의해 관리가 된다.

 

나중에 알게 되겠지만 결국 SecurityContext는 요청이 들어올 때 SecurityContextRepository에서 꺼낸 값으로 생성되며 SecurityContextHolder에 저장한 뒤 스프링 필터 체인 내에서 수차례 사용되고
응답하기 직전 SecurityContext값에 변동이 있으면 다시 SecurityContextRepository에 집어넣고 

SecurityContextHolder를 제거한다. 변동이 없으면 SecurityContextHolder만 제거한다.

댓글