-
스프링 시큐리티 레퍼런스프로그래밍 2022. 10. 24. 20:07반응형
spring security reference 5.7.4
Servlet Applications
- Sprint Security는 표준 서블릿 Filter를 이용하여 서블릿 컨테이너와 결합되있는 것으로 Servlet-based application에서는 사용하지 않아도 된다.
자동 설정
- springSecurityFilterChain 이라는 빈을 생성함으로써 서블릿 Filter를 자동 생성한다.
- UserDetailsService 빈을 자동 생성한다.
- 서블릿 컨테이너에 springSecurityFilterChain 빈을 자동으로 등록한다.
아키텍쳐
표준 서블릿 필터 리뷰
- 클라이언트가 request를 보내면, 컨테이너가 FilterChain을 생성한다.
FilterChain 사용 예제public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { // do something before the rest of the application chain.doFilter(request, response); // invoke the rest of the application // do something after the rest of the application }
DelegatingFilterProxy
- 스프링은 Filter 구현체로 DelegatingFilterProxy를 제공하고, 이는 서블릿 컨테이너의 생명 주기와 스프링의 ApplicationContext의 중간 다리가 된다. 서블릿 컨테이너는 Filter들의 등록을 허락하지만, 스프링 빈은 인식하지 못한다. DelegatingFilterProxy는 표준 서블릿 컨테이너 매커니즘을 통해 등록할 수 있지만 모든 작업을 Spring Bean에 위임한다.
- DelegatingFilterProxy는 ApplicationContext에서 Bean FIlter0을 찾고 Bean Filter0을 호출한다.public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { // Lazily get Filter that was registered as a Spring Bean // For the example in DelegatingFilterProxy delegate is an instance of Bean Filter0 Filter delegate = getFilterBean(someBeanName); // delegate work to the Spring Bean delegate.doFilter(request, response); }
FilterChainProxy
- 스프링 시큐리티는 FilterChainProxy를 통해 표준 서블릿 컨테이너를 지원한다.
- FilterChainProxy는 SecurityFilterChain을 통해 많은 Filter 인스턴스들을 위임한다.
- FilterChainProxy 또한 Bean이기 때문에, DelegatingFilterProxy로 wrap된다.
SecurityFilterChain
- 스프링 시큐리티 필터들 중에 어떤걸 호출할지 정한다.
- SecurityFilterChain 안의 SecurityFilter들은 모두 Bean이지만, DelegatingFilterProxy가 아닌 FilterChainProxy에 의해 등록된다.
- 이에 대한 장점은 첫번째로 모든 Spring Security's Servlet support에 대한 시작점을 제공하는 것이다. 예를 들어 디버깅을 할때, FilterChainProxy를 디버깅 포인트로 잡으면 쉽게 할 수 있다.
- 두번째는 FilterChainProxy가 스프링 시큐리티의 핵심이기 때문에 보이지 않는 task를 수행할 수 있다. 예를 들어 SecurityContext를 지움으로써 메모리 누수를 방지할 수 있고, HttpFirewall을 적용할 수도 있다.
- 세번째로 SecurityFilterChain 호출 시간 결정을 유연하게 만들어줄 수 있다. 예를 들어, 표준 서블릿 컨테이너에서는 URL만을 기반으로 필터를 호출하지만, FIlterChainProxy는 RequestMatcher 인터페이스를 이용하여 HttpServletRequest의 모든 항목을 기반으로 호출할수 있다.
- 만약 SecurityFilterChain 중 맞는 URL이 여러개라면 그중 첫번째만 호출된다.
- 첫번째 SecurityFilterChain은 세개의 필터만 설정할 수 있으나, 그 다음부터는 네개가 가능하다.
Authentication Architecture (detail)
SecurityContextHolder
- Spring Security's authentication model의 중심이고, SecurityContext를 포함한다.
- 누가 인증되었는지에 대한 세부 사항을 저장한다.
- 스프링 시큐리티는 SecurityContextHolder가 어떻게 채워져있는지 신경쓰지 않고 단지 값이 있으면 사용한다.
(직접 등록)SecurityContext context = SecurityContextHolder.createEmptyContext(); (1) Authentication authentication = new TestingAuthenticationToken("username", "password", "ROLE_USER"); (2) context.setAuthentication(authentication); SecurityContextHolder.setContext(context); (3)
(1) SecurityContextHolder 를 생성하지 않고 SecurityContext를 생성한 이유는 멀티쓰레드에서 Race condition을 피하기 위함이다.
(2) 새 Autentication 객체를 생성한다. 스프링 시큐리티는 Autentication 구현체에 대해 신경쓰지 않는다. TestingAutenticationToken을 사용한 이유는 간단해서이다. 보통은 UsernamePasswordAuthenticationToken(userDetails, password, authorities) 를 사용한다.
(3) SecurityContextHolder에 SecurityContext를 설정한다.
- 인증된 principal의 정보를 얻고 싶으면 SecurityContextHolder에 접근하면 된다.SecurityContext context = SecurityContextHolder.getContext(); Authentication authentication = context.getAuthentication(); String username = authentication.getName(); Object principal = authentication.getPrincipal(); Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
SecurityContext
- Authentication 객체를 포함한다.
Authentication
- AuthenticationManager의 input으로 사용되는데, credential을 제공한다.
- 현재 인증된 유저를 얻을 수 있다.
- 세가지를 포함하고 있는데, principal은 유저 정보이고, credentials는 비밀번호이고, authorities 도 포함한다.
AuthenticationManager
- 스프링 시큐리티 필터가 인증을 수행하는 방법을 정의하는 API(인터페이스)이다.
- Authentication 을 리턴한다.
- 구현체로 어떤것이든 가능하지만, 주로 ProviderManager를 사용한다.
ProviderManager
- AuthenticationProvider 들의 리스트를 위임한다. 각각은 인증 성공이나 실패, 인증 결정 불가 등을 나타낸다. 만약 등록된 것이 아무것도 없으면 ProviderNotFoundException이 발생한다.AbstractAuthenticationProcessingFilter
- 유저의 credential을 인증하는데 사용하는 기초 필터이다.
(1) 유저가 credential을 보내면 AAPF가 HttpServletRequest로부터 Authentication을 만든다. Authentication의 타입은 AAPF의 서브클래스에 의존한다. 예를 들어, UsernamePasswordAuthenticationFilter는 UsernamePasswordAuthenticationToken을 생성한다.
(2) Authentication은 AuthenticationManager로 보내진다.
(3) 만약 실패하면, SecurityContextHolder가 삭제되고, RememberMeServices.loginFail이 호출되고, AuthenticationFailureHandler가 호출된다.
(4) 성공하면, SessionAuthenticationStrategy가 새로운 로그인을 알리고, 뒤를 수행한다.반응형'프로그래밍' 카테고리의 다른 글
자바 서블릿 (Java Servlet) 정리 (0) 2022.10.31 Spring Web MVC 레퍼런스 (0) 2022.10.29 8. 블로그 프로젝트 (0) 2022.07.28 7. 블로그 프로젝트 (0) 2022.07.27 6. 블로그 프로젝트 (0) 2022.07.19