Authentication and Authorization

Filters (Servlet Filter Chain 구성)

Security filter chain:[
	WebAsyncManagerIntegrationFilter
	SecurityContextPersistenceFilter
	HeaderWriterFilter
	CsrfFilter
	LogoutFilter
	UsernamePasswordAuthenticationFilter  //프로세스 인증. default /login URL에 응답
	DefaultLoginPageGeneratingFilter
	DefaultLogoutPageGeneratingFilter
	BasicAuthenticationFilter
	RequestCacheAwareFilter
	SecurityContextHolderAwareRequestFilter
	AnonymousAuthenticationFilter         //인증 객체가 없을 때, 익명 인증 객체를 생성
	SessionManagementFilter
	ExceptionTranslationFilter            //스프링 시큐리티 예외 처리 AccessDeniedException을 해석하여 AuthenticationException을 Http 응답으로 바꿔준다
	FilterSecurityInterceptor             //액세스 거부 시 예외 발생
]

Spring Security 인증 관련 아키텍처

https://media.vlpt.us/images/sa833591/post/22bfb140-02b5-4fcf-aeed-8900d76044df/SecurityFilterChain2.JPG

1. SecurityContextHolder

Untitled

스프링 시큐리티로 인증한 사용자의 상세 정보를 저장한다. 스프링 시큐리티는 SecurityContextHolder 에 어떻게 값을 넣는지는 상관하지 않는다. 값이 있는 경우 인증한 사용자 정보로 사용한다

SecurityContextHolder 설정

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

SecurityContextHolder.setContext(context); // (3)

SecurityContextHolder 접근

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

기본적으로 SecurityContextHolderThreadLocal 을 사용하여 정보를 저장하기 때문에 메서드에 직접 SecurityContext 를 넘기지 않아도 동일 스레드라면 접근이 가능하다. 기존 principal 요청을 처리한 다음에 비워주는 것만 잊지 않으면 ThreadLocal을 사용해도 안전하다. 스프링 시큐리티의 FilterChainProxy가 항상 SecurityContext 를 비워준다