쌩로그

예외 처리 및 요청 캐시 필터 본문

Spring/Spring Security

예외 처리 및 요청 캐시 필터

.쌩수. 2023. 5. 17. 14:58
반응형

나는 어차피 잘 될 사람이다.

어차피 잘 될 것이고, 지금도 잘 되고있고, 과거도 잘 되어왔기에,,,


내가 굳이 목차를 적고, 이러는 이유... 말을 하거나, 쓸 때 두괄식으로 말하고자 하기 위함이다.
그리고 두괄식이 현재 나한텐 짱이다...

목차

  1. 포스팅 개요
  2. 본론
      2-1. FilterSecurityInterceptor
      2-2. ExceptionTranslationFilter 의 역할
        2-2-1. AuthenticationException(인증 예외)
        2-2-2. AccessDeniedException(인가 예외)
      2-3. ExceptionTranslationFilter의 흐름예외처리 API
      2-4. 예외처리 API
  3. 요약
  4. 끝.

1. 포스팅 개요

해당 포스팅은 인프런의 정수원님의 스프링 시큐리티를 기반으로 한 내용이다.

메서드 체이닝에 대한 내용은 깃허브 레포에 있다.

예외 처리요청정보를 캐싱하는 필터가 무엇인지에 대한 내용이다.

2. 본론

2-1. FilterSecurityInterceptor 와 ExceptionTranslationFilter

먼저 FilterSecurityInterceptor에 대해서 말해야할 거 같다.
FilterSecurityInterceptor스프링 시큐리티의 필터 중 맨 마지막에 위치한 Filter이다.

이 필터 앞에 위치한 필터가 ExceptionTranslationFilter이다.

결론부터 말하면, FilterSecurityInterceptor에서 던지는 예외(인증, 인가)를 ExceptionTranslationFilter이 받아서 처리한다.

💡참고 강의에서 나온 `FilterSecurityInterceptor`과 현재 `FilterSecurityInterceptor`가 다르다.
부트에서 Maven으로 라이브러리를 받아오지만, 부트가 알아서 라이브러리를 자신의 버전에 맞게 가져온 거 같다. 
현재 부트는 2.7버전이다. 그 이하를 선택하지 못 함;;)

사용자의 요청이 각 필터들을 거치다가, ExceptionTranslationFilter가 사용자의 요청을 받고 그 다음 Filter로 전달할 떄, try-catch로 FilterSecurityInterceptor를 감싼 후에 호출한다.

따라서 FilterSecurityInterceptor에서 발생하는 인증예외와 인가예외는 ExceptionTranslationFilter로 던진다.

그러면 ExceptionTranslationFilterFilterSecurityInterceptor가 던지는 예외들을 받아서 각각 처리한다.

다시 말하지만, FilterSecurityInterceptor에서 던지는 예외(인증, 인가)를 ExceptionTranslationFilter이 받아서 처리한다.

2-2. ExceptionTranslationFilter

ExceptionTranslationFilter는 두 가지의 예외를 처리한다.
인증 예외인가 예외이다.

즉 2-1 의 내용과 연결지어 말하면, FilterSecurityInterceptor가 던진 AuthenticationException(인증 예외)AccessDeniedException(인가 예외)을 처리한다.

2-2-1. AuthenticationException(인증 예외)

인증 예외가 발생하면 ExceptionTranslationFilter는 두 가지 처리를 한다.

  1. AuthenticationEntryPoint 인터페이스를 구현한 구현체를 호출해서 로그인 페이지로 이동시키거나, 401번의 오류 코드를 전달한다.
  2. 예외가 발생하기 전의 요청정보를 저장한다.
    // 1. 사용자가 user의 권한이 필요한 리소스에 접근하려고 할 때, 인증이 없이 접근하려고 한다.
    // 2. 접근을 하게되면 예외처리를 하게 되는데, 인증을 요청하기 이전에 사용자가 접근하려고 했던 요청정보(유저권한을 가지고 접근할 수 있는 resource 정보 등)를 캐싱한다.
    // 3.인증이 완료된 이후, RequestCache(인터페이스)구현체가 사용자가 접근하려던 요청페이지로 이동시킨다.
        // 3-1. RequestCache(인터페이스) : 캐시를 이용해서 사용자의 이전 요청 정보를 세션에 저장하고 꺼내온다.
        // 3-2. SavedRequest(인터페이스) : 사용자가 요청했던 요청 파라미터 값들, 그 당시의 헤더값들 등을 저장한다.
        // 3-3. SavedRequest(인터페이스)의 구현체의 예외가 발생하기 전의 요청정보를 저장하고, RequestCache(인터페이스)의 구현체가 SavedRequest(인터페이스)의 구현체를 세션에 저장되게 한다.

이 두가지 내용이 인증예외가 발생했을 때의 처리방식이다.

2-2-2. AccessDeniedException(인가 예외)

AccessDeniedHandler(인터페이스)의 구현체에서 예외 처리하도록 호출한다.
2-3 에서 조금 더 상세히 알아볼 수 있을 거 같다.

2-3. ExceptionTranslationFilter의 흐름

사용자가 인증없이 user자원에 접근한다고 가정한다!

  1. 사용자가 user 자원에 접근을 시도한다.
  2. FilterSecurityInterceptor(필터 맨 마지막에 위치)가 먼저는 인가 예외를 발생시킨다.
       ※ "왜 인증 예외가 아니냐?"할 것이다. 이유는 사용자가 인증을 하지않고 접근했기 때문에 익명사용자로 접근하게 되는 것이고, 결국 권한이 없다고 판단하여 인가 예외를 발생시킨다.
  3. ExceptionTranslationFilterAccessDeniedException(인가예외)을 발생시킨다.
       // 보통 인가 예외 발생시 AccessDeniedHandler(접근 거부시 처리 핸들러)로 처리되게 하지만, 익명사용자 혹은 RememberMe로 인증된 사용자라면, AuthenticationException(인증 예외)으로 처리하도록 하여 인증 예외로 넘긴다.

   결론은 AuthenticationException(인증 예외)으로 처리된다!!

  1. 인가예외를 거쳐서 AuthenticationException(인증 예외)가 발생한다. 인증 예외가 발생하면, 2-2에서 살펴본 것 처럼두 가지 처리를 한다.
      4-1. AuthenticationEntryPoint(인터페이스)의 구현체를 호출해서 SecurityContext안의 인증객체null로 만들고, 로그인 페이지로 이동하게 한다.
      4-2. 사용자가 user자원으로 접근하려고 할 때, 로그인페이지로 이동하기 이전에 사용자가 가고자했던 요청정보(url정보, 자원정보, 유저정보)를 저장하는데, 이 정보는 그림에서의 DefaultSavedRequest(검은색) 객체에 저장이 되고, 이 객체는 세션에 저장된다. 이 세션에 저장하는 역할을 HttpSessionRequestCache가 한다.

AccessDeniedException(인가예외)는 아래와 같다.

  1. AccessDeniedException(인가 예외)이 발생한다.
  2. AccessDeniedHandler(인터페이스)의 구현체를 호출하고 이후 처리를 한다.
  3. 보통은 접근이 거부되었을 때 메세지를 보여주는 페이지로 이동하거나, 권한을 변경해서 접근이 가능하도록 처리한다.

2-4. 예외처리 API

http.exceptionHandling() // 예외처리 기능이 작동함
    .authenticationEntryPoint(authenticationEntryPoint())    // 인증실패 시 처리 // 괄호()안에는 AuthenticationEntryPoint를 구현한 구현체를 담는다.
    .acessDeniedHandler(accessDeniedHandler())  // 인가실패시 처리 // 괄호()안에는 accessDeniedHandler를 구현한 구현체를 담아준다.

소스코드에서도 확인가능하다.

3. 요약

시큐리티 FIlter의 맨 마지막에 위치한 FilterSecurityInterceptor에서 발생한 인증 예외(AuthenticationException), 인가 예외(AccessDeniedException)ExceptionTranslationFilter가 처리한다.

4. 끝

728x90
Comments