본문 바로가기

SPRING/SpringSecurity

[스프링 시큐리티 완전 정복| 실전 프로젝트 | 회원 인증 시스템]RestAuthenticationSuccess(Failure)Handler

 

 

RestAuthenticationSuccessHandler

 

 



RestAuthenticationSuccessHandler는 Spring Security에서 인증 성공 후 처리를 담당하는 인증 성공 핸들러다. 주로 REST API에서 인증이 성공한 후에 추가적인 응답을 처리하거나, 커스텀 로직을 적용할 수 있도록 구현된다. REST API 환경에서는 페이지 리다이렉션 대신 JSON 응답을 반환하는 것이 일반적이므로, 이를 적절하게 처리하는 역할을 한다.

1. AuthenticationSuccessHandler란?

  • AuthenticationSuccessHandler는 사용자가 인증에 성공했을 때 호출되는 인터페이스로, 인증 성공 후의 동작을 정의한다.
  • 주로 페이지 기반 웹 애플리케이션에서는 인증 성공 시 사용자를 특정 페이지로 리다이렉션하는 역할을 하지만, REST API에서는 JSON 응답을 통해 인증 성공 결과를 반환하는 방식이 더 일반적이다.

2. RestAuthenticationSuccessHandler의 역할

  • REST API에서 인증이 성공하면, 리다이렉션 대신에 JSON 응답이나 다른 형식의 응답을 통해 클라이언트에게 인증 결과를 전달한다.
  • 주로 **상태 코드 200 (OK)**와 함께 인증된 사용자 정보토큰을 반환할 수 있다.
  • 성공한 인증 정보를 바탕으로, 추가적인 처리가 필요하면 그 작업을 수행한다. 예를 들어, JWT 토큰 생성 또는 사용자 세션 처리를 할 수 있다.

3. RestAuthenticationSuccessHandler의 기본 구조

RestAuthenticationSuccessHandler는 SimpleUrlAuthenticationSuccessHandler를 상속받아 구현하는 경우가 많으며, onAuthenticationSuccess 메서드를 오버라이드하여 커스텀 처리 로직을 작성할 수 있다.

 

 

 

 


코드 설명

@Component("restSuccessHandler")
// 이 클래스가 Spring Security의 AuthenticationSuccessHandler 빈으로 등록됨을 나타냄. 
// 빈 이름은 "restSuccessHandler"로 설정되어 있으며, REST API에서 인증 성공 시 이 핸들러가 호출된다.

public class RestAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {

        ObjectMapper mapper = new ObjectMapper();
        // Jackson의 ObjectMapper를 사용하여 Java 객체를 JSON으로 변환.

        AccountDto accountDto = (AccountDto) authentication.getPrincipal();
        // 인증된 사용자 정보를 Authentication 객체에서 가져옴. 이 경우, 사용자 정보는 AccountDto 타입으로 캐스팅됨.
        // AccountDto는 인증된 사용자 정보를 담고 있는 DTO(Data Transfer Object).

        response.setStatus(HttpStatus.OK.value());
        // HTTP 응답 상태 코드를 200 (OK)로 설정하여 인증이 성공했음을 나타냄.

        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        // 응답의 Content-Type을 "application/json"으로 설정하여 클라이언트에게 JSON 형식으로 데이터를 전달할 것임을 알림.

        accountDto.setPassword(null);
        // 비밀번호 정보를 보안상 이유로 응답에서 제거. 비밀번호는 인증이 성공한 후에는 클라이언트에게 노출되지 않도록 함.

        mapper.writeValue(response.getWriter(), accountDto);
        // AccountDto 객체를 JSON 형식으로 변환한 후, 응답 본문에 작성하여 클라이언트에게 전달. 
        // 클라이언트는 인증된 사용자 정보를 JSON 형식으로 응답받게 됨.

        clearAuthenticationAttributes(request);
        // 인증 과정 중에 발생한 잠재적인 인증 예외 정보를 세션에서 제거하여, 이후 요청에 영향을 미치지 않도록 함.
    }

    protected final void clearAuthenticationAttributes(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        // 현재 세션을 가져오되, 세션이 존재하지 않으면 null을 반환. (세션을 새로 생성하지 않음)

        if (session == null) {
            return;
        }
        // 세션이 없으면 아무 작업도 하지 않고 반환.

        session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
        // 세션에서 AUTHENTICATION_EXCEPTION 속성을 제거하여, 인증 예외 정보를 삭제. 
        // 이는 인증 성공 후 이전의 실패 정보가 남아있지 않도록 하기 위한 처리.
    }
}

RestAuthenticationFailureHandler

 



1. RestAuthenticationFailureHandler의 역할

  • REST API 환경에서 인증이 실패하면 상태 코드 401 (Unauthorized) 또는 400 (Bad Request) 등의 상태 코드와 함께 JSON 형식의 에러 메시지를 반환하여 클라이언트에게 실패 원인을 전달한다.
  • 인증 실패의 원인은 보통 잘못된 사용자 이름 또는 비밀번호, 계정 비활성화, 계정 잠금 등의 문제로 인해 발생할 수 있다.

2. RestAuthenticationFailureHandler의 동작 원리

  1. 인증 실패 시 호출
    • 사용자가 잘못된 자격 증명(사용자 이름/비밀번호)을 입력하거나, 계정이 비활성화된 상태에서 로그인하려고 시도하면 Spring Security는 이 핸들러의 onAuthenticationFailure 메서드를 호출한다.
  2. HTTP 응답 상태 코드 설정
    • 응답 상태 코드를 401 (Unauthorized)로 설정하여, 클라이언트에게 인증 실패를 알린다. 이 상태 코드는 인증이 필요한 요청에서 자격 증명이 잘못되었을 때 반환된다.
  3. JSON 형식으로 에러 메시지 반환
    • 응답의 Content-Type을 application/json으로 설정하여 클라이언트에게 JSON 응답임을 명확히 한다.
    • 인증 실패의 원인(예: 비밀번호 오류, 계정 잠금 등)을 나타내는 메시지를 JSON 형식으로 클라이언트에게 전달한다.
  4. 추가적인 실패 정보 설정
    • 실패 응답에 포함될 데이터를 설정한다. 일반적으로 타임스탬프, 상태 코드, 그리고 실패 원인(예외 메시지)이 포함된다. 예외 메시지는 AuthenticationException에서 가져와서 실패 원인에 따라 다르게 처리할 수 있다.
  5. JSON 응답 전송
    • ObjectMapper를 사용하여 설정된 데이터를 JSON 형식으로 변환하고, 이를 응답 본문에 기록하여 클라이언트에게 전송한다. 클라이언트는 이 데이터를 받아서 인증 실패에 대한 상세 정보를 확인할 수 있다.
 

 

 

 


코드 설명

@Component("restFailureHandler")
// 이 클래스가 Spring Security의 AuthenticationFailureHandler 빈으로 등록됨을 나타냄. 
// 빈 이름은 "restFailureHandler"로 설정되어 있으며, REST API에서 인증 실패 시 호출되는 핸들러 역할을 함.

public class RestAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {

        ObjectMapper mapper = new ObjectMapper();
        // Jackson의 ObjectMapper를 사용해 Java 객체를 JSON 형식으로 변환할 준비. 실패 메시지를 JSON으로 변환하여 응답할 때 사용됨.

        response.setStatus(HttpStatus.UNAUTHORIZED.value());
        // 응답 상태 코드를 401 Unauthorized로 설정. 이는 인증이 실패했음을 나타내는 표준 HTTP 상태 코드임.

        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        // 응답의 Content-Type을 application/json으로 설정하여 클라이언트에게 JSON 형식의 데이터를 반환할 것임을 명시.

        if (exception instanceof BadCredentialsException) {
            // 발생한 예외가 BadCredentialsException(잘못된 사용자 이름 또는 비밀번호)인 경우.
            mapper.writeValue(response.getWriter(), "Invalid username or password");
            // "Invalid username or password"라는 메시지를 JSON 형식으로 변환하여 응답 본문에 작성.
        }

        mapper.writeValue(response.getWriter(), "Authentication failed");
        // 그 외의 경우(다른 유형의 인증 실패)에는 "Authentication failed" 메시지를 응답 본문에 작성. 
        // 단, 이전에 메시지를 기록한 경우에도 이 줄이 실행되므로 두 번의 응답이 기록됨. (버그 가능성 있음)
    }
}