반응형
인프런에서 진행하는 정수원 강사님의 "스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security" 강의를 보고 학습을 위해 개인적으로 추가/정리한 글임을 알립니다.
인증/인가 API
ExceptionTranslationFilter
FilterSecurityInterceptor(맨 마지막에 위치)가 이를 호출한다
ExceptionTranslationFilter 필터는 아래 두가지 예외를 처리하고 있다.
AuthenticationException
- 인증 예외 처리
- AuthenticationEntryPoint 호출
- 로그인 페이지 이동
- 401 오류 코드 전달 등
- 인증 예외가 발생하기 전의 요청 정보를 저장
- RequestCache : 사용자의 이전 요청 정보를 세션에 저장하고 이를 꺼내 오는 캐시 메커니즘을 제공
- *SavedRequest * : 사용자가 요청했던 request 의 파라미터 값들, 그 당시의 헤더값 들이 저장
- AuthenticationEntryPoint 호출
- 인증 예외 처리
AccessDeniedException
- 인가 예외 처리
- AccessDeniedHandler 에서 예외 처리하도록 제공
- 인가 예외 처리
유저가 /user
자원 접근을 시도하고 있다면 FilterSecurityInterceptor에서 엄밀히 말해서는 익명사용자 이기 때문에 인증 예외가 아니라, 인가 예외로 빠지게 된다.
이 ExceptionTranslationFilter가 인가 예외로 보내긴 하지만 AccessDeniedHandler 로 곧바로 보내지 않고, HttpSessionRequestCache로 보내버린다.
따라서, 쉽게 생각해서 인증 예외의 과정으로 보내어진다고 보면 된다.
인증예외파트에서는 두 가지 일을 하게 된다.
- 인증 실패 이후 처리
- Security Context안에 있는 인증 객체를 null로 만든다.
- AuthenticationEntryPoint 에서 다시 인증할 수 있도록 로그인 페이지로 보내버리고
- 사용자의 요청관련 정보 저장
- 예외가 발생하기 이전의 유저정보를 저장한다.
- 이 정보는 DefaultSavedRequest 객체 안에 저장되고 이 객체는 Session에 저장한다.
- 그 역할을 HttpSessionRequestCache 클래스가 수행한다.
만약에 유저가 /user
페이지가 아니라, /admin
자원에 접근하려고 한다면 인가예외가 발생한다.
ExceptionTranslationFilter는 AccessDeniedException이 발생하고 AccessDeniedHandler 를 호출해서 그 안에서 후속처리를 처리한다.
(보통은 /denied
페이지를 redirect 한다. 또는 이 자원에 다시금 접근할 수 있도록 조정할 수 있는 처리를 하게 된다.)
> 예외처리 과정
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint()) // 인증실패 시 처리
.accessDeniedHandler(accessDeniedHandler()) // 인가실패 시 처리
;
}
protected void configure(HttpSecurity http) throws Exception {
http
.successHandler(new AuthenticationSuccessHandler() { // 로그인 성공 시 호출하는 핸들러
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
System.out.println("authentication: " + authentication.getName());
httpServletResponse.sendRedirect("/");
// 이미 인증예외 필터에서 RequestCache에 캐시정보가 세션에 담겨 있으므로 불러와서 사용가능하다.
RequestCache requestCache = new HttpSessionRequestCache();
SavedRequest savedRequest = requestCache.getRequest(httpServletRequest, httpServletResponse);
String redirectUrl = savedRequest.getRedirectUrl();
httpServletResponse.sendRedirect(redirectUrl);
}
})
;
http
.exceptionHandling()
.authenticationEntryPoint(new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
// login만 인증을 받지 않아도 그 자원에 접근할 수 있어야 한다. -> 인가처리를 따로 해줘야 한다.
response.sendRedirect("/login");
}
})
.accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.sendRedirect("/denied");
}
})
;
}
그리고 이 때 sendRedirect 할 때는 Spring-Security에서 제공하는 페이지가 아니기 때문에 직접 페이지를 만들어줘야 한다.
반응형
'웹 프로그래밍 > [ Spring Security ]' 카테고리의 다른 글
[ Spring Security ] 07. 주요 아키텍쳐 : DelegatingFilterProxy & FilterChainProxy (0) | 2021.12.20 |
---|---|
[ Spring Security ] 06. CSRF Filter (0) | 2021.12.12 |
[ Spring Security ] 04. 인가 API와 표현식 (0) | 2021.12.09 |
[ Spring Security ] 03. 동시 세션제어와 세션 고정보호, 세션 정책 관리 (0) | 2021.12.08 |
[ Spring Security ] 02. 익명 사용자 인증처리 필터 : AnonymousAuthenticationFilter (0) | 2021.12.08 |