예외 처리

enxnong·2024년 6월 18일
0

스프링 시큐리티

목록 보기
5/13

정수원님의 강의 스프링 시큐리티 완전 정복 [6.x 개정판] 보면서 공부한 내용입니다.

예외처리

exceptionHandling()

  • 필터 체인 내에서 발생하는 예외를 의미하며 인증예외, 인가예외로 나눌 수 있다
  • 사용자의 인증 및 인가 상태에 따라 로그인 재시도, 401, 403 코드 등으로 응답할 수 있다

예외처리 유형

  • AuthenticationException (인증예외)
    • SecurityContext에서 인증 정보 삭제
      → 기존의 인증이 더 이상 유효하지 않다고 생각하여 초기화(null 상태)
    • AuthenticationEntryPoint 호출
      → 인증을 시도할 수 있는 화면(ex: 로그인화면)으로 이동한다
    • 인증 프로세스의 요청 정보를 저장하고 검색
      → RequestCache & SavedRequest 클래스로 세션에 요청정보를 저장한다. 이후 인증 완료 시 요청을 검색해서 재 사용할 수 있다.
  • AccessDeniedException (인가예외)
    • AccessDeniedHandler 호출
      → 사용자가 익명 사용자인지 판단하여 익명 사용자인 경우 인증예외처리가 실행되고 익명 사용자가 아닌 경우 403 코드를 응답하여 접근이 거부되었다는 메세지를 띄운다.

exceptionHandling() API

    /**
     * 예외 처리 - exceptionHandling()
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

        http
            .authorizeHttpRequests(auth -> auth
                    .requestMatchers("/login").permitAll()
                    .requestMatchers("/admin").hasRole("ADMIN") // admin 사용자만 접근 가능, 이외는 인가 예외 발생
                    .anyRequest().authenticated())
            .formLogin(Customizer.withDefaults())
            .exceptionHandling(exception -> exception
                    .authenticationEntryPoint(new AuthenticationEntryPoint() { // 인증 예외
                        @Override
                        public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                            System.out.println("exception : " + authException.getMessage());
                            response.sendRedirect("/login"); // 로그인 페이지로 이동
                        }
                    })
                    .accessDeniedHandler(new AccessDeniedHandler() { // 인가 예외
                        @Override
                        public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
                            System.out.println("exception : " + accessDeniedException.getMessage());
                            response.sendRedirect("/denied"); // denied 페이지로 이동
                        }
                    })
            );
        return http.build();
    }
  • authenticationEntryPoint()
    • UsernamePasswordAuthenticationFIlter - LoginUrlAuthenticationEntryPoint
      → 로그인 페이지로 이동시킴 (기본 설정 클래스)
    • BasicAuthenticationFilter - BasicAuthenticationEntryPoint
      → 기본 인증 실패했을 때 처리하는 클래스
    • 인증 프로세스가 설정되지 않았을 때는 기본적으로 Http403ForbiddenEntryPoint가 사용된다
    • 사용자 정의 AuthenticationEntryPoint 구현이 가장 우선적으로 수행되며 이 때는 기본 로그인 페이지 생성이 무시된다
      → 인증 실패 시 사용자 정의한 페이지로 이동할 것이라고 생각하기 때문에 LoginUrlAuthenticationEntryPoint가 무시됨 (로그인 페이지로 이동하도록 직접 설정해야한다)

  • accessDeniedHandler
    • 기본적으로 AccessDeniedHandlerImple 클래스가 사용됨

예외 필터

ExceptionTranslationFilter

  • 익명 사용자
  1. 인증을 받지 못한 사용자가 request로 요청
  2. AuthorizationFilter을 통해 요청 처리 (현재 사용자가 요청한 경로로 접근이 가능한지 불가능한지 확인 - 인가 가능 필터)
  3. 접근이 불가능하면 AuthorizationManger을 통해 사용자의 접근 요구를 판단하여 최종 return받은 값으로 AccessDeniedException을 발생시킴
  4. 인가 예외가 발생했기에 ExceptionTranslationFilter가 익명 사용자인지 기억하기 인증(아이디와 패스워드를 사용하여 인증 받은 상태가 아닌) 통해 들어온 사용자인지 확인 → 둘 중 하나라도 속하면 AccessDeniedHandler 발생하지 않고 AuthenticationException (예외 처리)로 가서 해당 예외처리 관련 기능 수행

  • 인증 받은 사용자
  1. 인증을 받은 사용자(아이디와 패스워드를 사용)가 request로 요청
  2. AuthorizationFilter을 통해 요청 처리 (현재 사용자가 요청한 경로로 접근이 가능한지 불가능한지 확인 - 인가 가능 필터)
  3. 접근이 불가능하면 AuthorizationManger을 통해 사용자의 접근 요구를 판단하여 최종 return받은 값으로 AccessDeniedException을 발생시킴
  4. 인가 예외가 발생했기에 AccessDeniedHandler실행하여 해당 예외처리 관련 기능 수행
profile
높은 곳을 향해서

0개의 댓글