[400] AuthenticationFailureHandler (인증 실패 핸들러: 로그인 실패 핸드러)
@Slf4j
@RequiredArgsConstructor
public class LoginFailHandler implements AuthenticationFailureHandler {
private final ObjectMapper objectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
log.info("[인증 오류] 아이디 혹은 비밀번호가 올바르지 않습니다.");
ErrorResponse errorResponse = ErrorResponse.builder()
.code("400")
.message("아이디 혹은 비밀번호가 올바르지 않습니다.")
.build();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
objectMapper.writeValue(response.getWriter(), errorResponse);
}
}
사용자의 잘못된 요청(아이디 혹은 비밀번호가 틀린 경우): 400 BAD_REQUEST
ErrorResponse(커스텀 객체) 반환
[401] AuthenticationEntryPoint (권한이 필요한 경우: 로그인을 안한 상태)
@Slf4j
@RequiredArgsConstructor
public class Http401Handler implements AuthenticationEntryPoint {
private final ObjectMapper objectMapper;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
log.info("[인증 오류] 로그인이 필요합니다.");
ErrorResponse errorResponse = ErrorResponse.builder()
.code("401")
.message("로그인이 필요합니다")
.build();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
objectMapper.writeValue(response.getWriter(), errorResponse);
}
}
403 UNAUTHORIZED
[403] AccessDeniedHandler(접근 불가 처리 핸들러)
@Slf4j
@RequiredArgsConstructor
public class Http403Handler implements AccessDeniedHandler {
private final ObjectMapper objectMapper;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
log.info("[인증 오류] 권한이 부족합니다.");
ErrorResponse errorResponse = ErrorResponse.builder()
.code("403")
.message("권한이 부족합니다.")
.build();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
objectMapper.writeValue(response.getWriter(), errorResponse);
}
}
로그인은 했지만 접근 권한이 없는 경우
EX)
관리자 권한만 접근 가능한 페이지에 접속하려고 하는 경우 hasRole("ADMIN")
403 FORBIDDEN
핸들러 SecurityFilterChain 설정
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
return http
.authorizeHttpRequests(
authorize -> authorize
.requestMatchers("/auth/login").permitAll()
.requestMatchers("/auth/signup").permitAll()
.requestMatchers("/user").hasRole("USER")
.requestMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated())
.csrf(AbstractHttpConfigurer::disable)
.formLogin(login -> login
.loginPage("/auth/login")
.loginProcessingUrl("/auth/login")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/")
.failureHandler(new LoginFailHandler(objectMapper))
)
.rememberMe(rm -> rm
.rememberMeParameter("remember")
.alwaysRemember(false)
.tokenValiditySeconds(2592000))
.exceptionHandling(e -> {
e.accessDeniedHandler(new Http403Handler(objectMapper));
e.authenticationEntryPoint(new Http401Handler(objectMapper));
})
.build();
}
AuthenticationEntryPoint, AccessDeniedHandler
.exceptionHandling(e -> {
e.accessDeniedHandler(new Http403Handler(objectMapper));
e.authenticationEntryPoint(new Http401Handler(objectMapper));
})
권한 부족, 권한이 없는 경우 처리
AuthenticationFailureHandler
.formLogin(login -> login
.loginPage("/auth/login")
.loginProcessingUrl("/auth/login")
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("/")
.failureHandler(new LoginFailHandler(objectMapper))
)
로그인 실패 처리
'Spring > Spring Security' 카테고리의 다른 글
[Spring Security] 요청 캐시 흐름 정리 (1) | 2024.09.13 |
---|---|
[Spring Security] 로그인 사용자 정보 가져오기 (0) | 2024.09.03 |
[Spring Security] ROLE VS AUTHORITY (0) | 2024.09.02 |
[Spring Security] UserDetailsService (0) | 2024.09.02 |
[Spring Security] Remember Me (0) | 2024.09.02 |