목록
1. DefaultLoginPageGeneratingFilter & DefaultLogoutPageGeneratingFilter
2. BasicAuthenticationFilter
-Basic 인증?
3. RequestCacheAwareFilter
4. SecurityContextHolderAwareRequestFilter
5. AnonymousAuthenticationFilter
-Null Object Pattern
6. SessionManagementFilter
-세션 변조?
7. ExceptionTranslationFilter
8. FilterSecurityInterceptor
이 두 필터들 역시 이름처럼 기본 로그인, 로그아웃 페이지를 제공해주는 필터이다. /login 으로 get 요청을 보낼 경우 기본적으로 제공해주는 로그인페이지로 보내주고 /logout 으로 get 요청을 보낼 경우 기본적으로 제공하는 로그아웃 페이지를 보내준다. 만약 커스텀한 로그인-아웃 페이지를 사용하고 싶다면
시큐리티 설정파일에서 직접 로그인페이지로 갈 url 을 맵핑시켜주기만 하여도 DefaultLoginPageGeneratingFilter 와 DefaultLogoutPageGeneratingFilter 는 FilterChainProxy에서 빠지는 것을 확인할 수 있다.
그리고, 직접 로그인 페이지와 로그아웃 페이지를 구현하면 된다.
물론 구현할 페이지와 configuration 클래스에서 설정한 값들은 맞춰주어야 한다.
이 필터는 설정 클래스에서
다음과 같이 설정을 해두면 HttpBasic 인증을 지원하는 필터를 포함한 FilterChainProxy를 제공해준다.
요청 헤더에 username 과 password를 (username:password) 를 Base64 로 인코딩한 값을 실어서 보내는 것이다.
이 필터를 이용하면, 이전에 폼요청으로 받아온 데이터로 UsernamePasswordAuthenticaton 토큰을 생성하지 않아도, 요청 헤더의 정보를 사용하여 UsernamePasswordAuthenticaton 토큰을 생성할 수 있다.
토큰이 생성된 이후의 과정은 UsernamePasswordAuthenticationFilter 의 과정과 동일하다.
현재 요청과 관련있는 캐시 요청이 있는지 확인하고 있다면 캐시 요청을 처리해준다.
예를들어 설명하자면, 로그인을 하지 않은채 로그인을 필요로하는 페이지로 요청을 보내면, AccessDecisionManager 의 판단하에 로그인 페이지로 이동하게 되고 로그인 이후에 '캐시해둔 목적지 페이지로의 요청'을 처리해 가려했던 페이지로 이동하게 되는 것이다.
시큐리티 관련 서블릿 API 를 지원해주는 필터이다.
SecurityContext 에 Authentication 이 null 일 경우 AnonymousAuthentication을 만들어 넣어주는 과정이 일어나는 필터이다.
만약 SecurityContext 에 Authentication 이 있다면 넘어간다.
위 코드를 보면 if 문에서 holder 에서 context를 꺼내와 authentication 의 null 체크를 하고 null 이면 createAuthentication을 해주는 모습을 볼 수 있다.
이 필터를 통해 Null Object Pattern 을 사용(?)할 수 있게 된다. 이 패턴은 Null 대신 Null 을 대변할 수 있는 객체를 사용하는 패턴인데, null 검사의 필요를 제거하고, 코드를 단순화하는데 도움이될 수 있기 때문에 사용되는 패턴이지만, 문제를 감지하거나 찾기가 힘들어질 때도 있다는 단점이 있다.
해당 필터에서는 여러가지 일들을 처리하는데,
1.세션 변조 방지 전략을 설정하고
2.유효하지 않은 세션을 Redirect 시킬 URL을 설정하고
3.동시성 제어 설정
4.세션생성전략 설정
을 할 수 있다.
가장 간단하게 세션 변조를 막는 방법은 인증을 했을 때 세션을 바꿔버리는 것이다. 서블릿 3.0 이전버전의 컨테이너를 사용하면, migrateSession (인증을 하면 세션을 새로 생성해(세션아이디는 당연히 변경된다), 기존 세션에 있던 정보들을 복사해 넣어준다.) 서블릿 3.1 이후버전에서는 changeSessionId 전략을 사용하는데 세션아이디만 바꿔침으로써 문제를 해결한다.
동시성 제어의 경우 스프링 시큐리티의 기본값은 동시접속이 가능하게 되어있다. 원한다면 설정을 통해 최대접속수를 제한할 수 있다.
다음과 같이 설정하면 동시접속이 불가능하고, 기본전략은 새로 로그인 하면 기존 로그인한 곳에서 세션은 invalidate 된다.
세션 생성 전략의 경우
1. IF_REQUIRED (default)
2. NEVER
3. STATELESS
4. ALWAYS
가 있는데,
IF_REQUIRED -> 필요할 때 만들어 쓰겠다
NEVER -> 시큐리티에서는 세션을 만들지 않지만 기존에 세션이 있다면 그 세션을 사용하겠다.
STATELESS -> 세션을 사용하지 않는다.
ALWAYS -> 항상 만듬
이 필터는 바로 다음에 알아볼 FilterSecurityInterceptor 와 연계가 강하게 되는 필터인데, FilterSecurityInterceptor 가 AccessDecisionManager 를 통해 AuthenticationException 혹은, AccessDeniedException 을 발생시킨 경우 해당 Exception을 받아 AuthenticationException의 경우 AuthenticationEntryPoint 로 보내주고, AccessDeniedException 의 경우에는 AccessDeniedHandler 로 보내는 역할을 담당한다.
시큐리티를 사용한다면 아마도 가장 먼저 건드려보았을 이 설정이 바로 FilterSecurityInterceptor 의 설정을 하는 것이다.
이 설정을 통해 인증이 필요한 접근인지, 어떠한 권한이 필요한지를 설정할 수 있다.
*참고: 이 포스팅은 백기선님의 스프링시큐리티 강의를 듣고, 제 나름대로 다시 공부하고 정리한 포스팅 입니다. 만약, 조금 더 자세한 내용을 듣고 싶으시다면 이곳의 강의를 참고해보시기 바랍니다