ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스프링 시큐리티] ExceptionTranslationFilter
    강의노트/스프링 시큐리티 2020. 9. 12. 13:25

    ExceptionTranslationFilter 필터의 경우 아래 2가지 예외를 발생시킨다.

    인증 예외 (AuthenticationException)

    • AuthenticationEntryPoint 호출
      • 로그인 페이지 이동, 401 오류 코드 전달, SecurityContext 초기화
      • AuthenticationEntryPoint를 직접 구현해서 인증 예외 처리를 할 수도 있다.
      • this.authenticationEntryPoint.commence(request, response, reason);
    • 인증 예외가 발생하기 전의 요청 정보를 저장
      • RequestCache 인터페이스 : 사용자의 이전 요청 정보를 세션에 저장하고 이를 꺼내 오는 캐시 메커니즘
        • 사용자가 다시 로그인하여 성공 후 이전 가고자 했던 리소스 정보를 캐시에서 가지고 와서 해당 리소스로 이동하게 됨
        • SavedRequest 인터페이스 : 사용자가 요청했던 request paramter, header 값들을 저장
      • this.requestCache.saveRequest(request, response);

    ReequestCacheAwareFilter

    RequestCacheAwareFilter는 requestCache에 값이 존재하는 경우 해당 값을 꺼내서 다음 Filter로 넘겨주는 역활을 한다.

    ExceptionTranslationFilter

    RequestCacheAwareFilter에서 전달 된 requestCache의 값을 가지고 인증 성공 시 이전 요청된 정보를 가지고 해당 리소스로 이동한다.

    인가 예외 (AccessDeniedException)

    • AccessDeniedHandler에서 예외를 처리하도록 호출
      • /denied 페이지로 이동

    인증 & 인가 예외 처리 구현

    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatchers("/users/**")
             .authorizeRequests()
                .antMatchers("/login").permitAll()
                .antMatchers("/shop/login", "/shop/users/**").permitAll()
                .antMatchers("/shop/mypage").hasRole("ROLE_USER")
                .antMatchers("/shop/admin/pay").access("hasRole('ROLE_ADMIN')")
                .antMatchers("/shop/admin/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_SYS')")
                .anyRequest().authenticated()
    
        http
            .formLogin()
            .successHandler(new AuthenticationSuccessHandler() {
                @Override
                public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                    // 인증 성공 후 Session에 저장된 이전 요청 정보를 꺼내와서 이동하도록 처리
                    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 httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                    httpServletResponse.sendRedirect("/login");
                }
            })
            .accessDeniedHandler(new AccessDeniedHandler() {                // 인가 실패 시 처리
                @Override
                public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                    httpServletResponse.sendRedirect("/denied");
                }
                 });
    }

    최초 인증되지 않은 클라이언트 접근 시 동작

    • 익명 사용자가 접근하기 때문에 인가 예외로 처리
    • 익명 사용자 또는 remember-me인경우 AccessDeniedException 발생 시 AccesssDeniedHander로 안보내고 AuthenticationException으로 이동한다.

    ExceptionTranslationFilter

    댓글

Designed by Tistory.