Authentication (인증) : 사용자의 식별, 신원 확인
Authorization (인가) : 사용자가 권한이 있는지 여부를 결정
Spring security에서 인증/인가에 대한 예외처리는 ExceptionTranslationFilter
가 수행한다.
이 필터는 AuthenticationException
과 AccessDeniedException
을 처리하는데, 각각 인증 예외와 인가 예외를 처리한다.
fitlerChain에 예외처리 등록
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.
...
.and().exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
.accessDeniedHandler(customAccessDeniedHandler);
return http.build();
}
## 인증 예외 - AuthenticationException
CustomAuthenticationEntryPoint
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException, ServletException {
response.sendRedirect("/auth/not-secured");
}
}
인증 예외가 발생하면 등록한 CustomAuthenticationEntryPoint가 수행되고, 지정한 /auth/not-secured
로 리다이렉트 시킨다.
@Controller
@RequestMapping("/auth")
@RequiredArgsConstructor
public class SecurityController {
@GetMapping("/not-secured")
public ResponseEntity notSecured(){
return new ResponseEntity(
new Response(401, "로그인이 되지 않았습니다."), HttpStatus.UNAUTHORIZED
); // 권한이 여러개일 경우에는 따로 설정해주어야 한다.
}
}
customAccessDeniedHandler
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Setter
private String errorURL;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
String deniedUrl = errorURL + "?message=" + accessDeniedException.getMessage();
response.sendRedirect(deniedUrl);
}
}
요쳥이 거부된 URL와 에러 메세지를 포함하여 deniedUrl로 리다이렉트
@Controller
@RequestMapping("/auth")
@RequiredArgsConstructor
public class SecurityController {
@GetMapping("/denied")
public ResponseEntity failedSecure(@RequestParam String message){
return new ResponseEntity(
new Response(403, message), HttpStatus.NOT_ACCEPTABLE
);
}
}