Verifies you are who you say are ex) email, username
Login Form, Http Authentication, Custom Auth, Method
예) 빌딩에 들어갈 수 있는가
Security filter chain:[
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
UsernamePasswordAuthenticationFilter //프로세스 인증. default /login URL에 응답
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter //인증 객체가 없을 때, 익명 인증 객체를 생성
SessionManagementFilter
ExceptionTranslationFilter //스프링 시큐리티 예외 처리 AccessDeniedException을 해석하여 AuthenticationException을 Http 응답으로 바꿔준다
FilterSecurityInterceptor //액세스 거부 시 예외 발생
]
스프링 시큐리티로 인증한 사용자의 상세 정보를 저장한다. 스프링 시큐리티는 SecurityContextHolder
에 어떻게 값을 넣는지는 상관하지 않는다. 값이 있는 경우 인증한 사용자 정보로 사용한다
SecurityContextHolder 설정
SecurityContext context = SecurityContextHolder.createEmptyContext(); // (1)
Authentication authentication =
new TestingAuthenticationToken("username", "password", "ROLE_USER"); // (2)
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context); // (3)
SecurityContext
를 만든다. SecurityContextHolder.getContext().setAuthentication()
사용 시 스레드 경합이 발생하므로 사용하면 안된다.Authentication
객체를 생성한다. Authentication
구현체라면 SecurityContext
에 담을 수 있다. 프로덕션 환경에서는 UsernamePasswordAutenticationToken(userDetails, password, authorities)
를 주로 사용한다SecurityContextHolder
에 SecurityContext
를 설정해준다SecurityContextHolder 접근
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
String username = authentication.getName();
Object principal = authentication.getPrincipal();
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
기본적으로 SecurityContextHolder
는 ThreadLocal
을 사용하여 정보를 저장하기 때문에 메서드에 직접 SecurityContext
를 넘기지 않아도 동일 스레드라면 접근이 가능하다. 기존 principal 요청을 처리한 다음에 비워주는 것만 잊지 않으면 ThreadLocal
을 사용해도 안전하다. 스프링 시큐리티의 FilterChainProxy가 항상 SecurityContext
를 비워준다