인프런/스프링 시큐리티 완전 정복 [6.x 개정판]

7) 인증 아키텍처 - Authentication , SecurityContext / SecurityContextHolder

backend dev 2024. 10. 14.

인증 ­- Authentication

 

 

 

인증은 특정 자원에 접근하려는 사람의 신원을 확인하는 방법을 의미한다

 

• 사용자 인증의 일반적인 방법은 사용자 이름과 비밀번호를 입력하게 하는 것으로서

인증이 수행되면 신원을 알고 권한 부여를 할 수 있다

 

Authentication 은 사용자의 인증 정보를 저장하는 토큰 개념의 객체로 활용되며

인증 이후 SecurityContext 에 저장되어 전역적으로 참조가 가능하다

 

• getPrincipal() ­ 인증 주체를 의미하며 인증 요청의 경우 사용자 이름을, 인증 후 에는 UserDetails 타입의 객체가 될 수 있다

• getCredentials() - 인증 주체가 올바른 것을 증명하는 자격 증명으로서 대개 비밀번호를 의미한다

• getAuthorities() ­ 인증 주체(principal)에게 부여된 권한을 나타낸다

• getDetails() - 인증 요청에 대한 추가적인 세부 사항을 저장한다. IP 주소, 인증서 일련 번호 등이 될 수 있다

• isAuthenticated() ­ 인증 상태 반환 한다 

• setAuthenticated(boolean) ­ 인증 상태를 설정한다

 

 

 


SecurityContext  /  SecurityContextHolder

 

 

SecurityContext

SecurityContextHolder

SecurityContextHolder 저장 모드

 

 

SecurityContextHolderSecurityContextHolderStrategy라는 인터페이스를 속성으로 가진다.

 

 

void clearContext(); // 현재 컨텍스트를 삭제한다
SecurityContext getContext(); // 현재 컨텍스트를 얻는다
Supplier<SecurityContext> getDeferredContext() // 현재 컨텍스트를 반환하는 Supplier 를 얻는다
void setContext(SecurityContext context); // 현재 컨텍스트를 저장한다
void setDeferredContext(Supplier<SecurityContext> deferredContext) // 현재 컨텍스트를 반환하는 Supplier 를 저장한다
SecurityContext createEmptyContext(); // 새롭고 비어 있는 컨텍스트를 생성한다

 

 

SecurityContext 참조 및 삭제

SecurityContext 참조 - SecurityContexHolder.getContextHolderStrategy().getContext()

SecurityContext 삭제 - SecurityContexHolder.getContextHolderStrategy().clearContext()

 

 

SecurityContextHolder & SecurityContext 구조

 

[http Request에 대해 각각 쓰레드가 할당되고, 해당 쓰레드의 쓰레드 로컬에는 SecurityContext가 각각 존재한다.]

 

• 스레드 마다 할당 되는 전용 저장소에 SecurityContext 를 저장하기 때문에 동시성의 문제가 없다

 

• 스레드 풀에서 운용되는 스레드일 경우 새로운 요청이더라도 기존의 ThreadLocal 이 재사용될 수 있기 때문에

클라이언트로 응답 직전에 항상 SecurityContext 를 삭제 해 주고 있다

 

SecurityContextHolderStrategy 사용하기

 

기존 방식

SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);

 

위 코드는 SecurityContextHolder 를 통해 SecurityContext 에 정적으로 접근할 때

여러 애플리케이션 컨텍스트가 SecurityContextHolderStrategy 를 지정하려고 할 때 경쟁 조건을 만들 수 있다

[SecurityContextHolderStrategy를 공유하기 때문에 각각의 어플리케이션 컨텍스트가 하나의 SecurityContextHolderStrategy에 접근 할 수 있기 때문 ] 

 

변경 방식

SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
SecurityContext context = securityContextHolderStrategy.createEmptyContext();
context.setAuthentication(authentication);
securityContextHolderStrategy.setContext(context);

 

애플리케이션이 SecurityContext를 정적으로 접근하는 대신 SecurityContextHolderStrategy

자동 주입이 될 수 있도록 한다 각 애플리케이션 컨텍스트는 자신에게 가장 적합한 보안 전략을 사용할 수 있게 된다

 

 

 

 

댓글