Backend/Spring Security

permitAll 설정의 의미

olsohee 2024. 1. 22. 15:50

우리는 다음과 같이 permitAll을 통해 인증 정보 없이 누구나 접근 가능한 리소스를 지정할 수 있다.

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

    http.authorizeHttpRequests(authHttp ->
                    authHttp.requestMatchers(POST, "/join", "/login").permitAll())
                    ...
                    
    return http.build();
}

 

그러나 커스텀 필터와 함께 permitAll을 사용할 때는 주의할 점이 있다. permitAll() 설정 유무에 대한 차이를 명확히 알아야 하는데, permitAll에 대해 공식 문서에는 다음과 같이 나와있다.

permitAll - The request requires no authorization and is a public endpoint; note that in this case, the Authentication is never retrieved from the session

 

즉 permitAll로 설정한 경로든 아니든 필터가 적용되는 건 같다. 단, permitAll로 설정한 경로는 모든 필터를 처리한 후에 SecurityContext에 인증 정보(Authentication)가 없어도 예외를 발생시키지 않는다. 반면 permitAll로 설정하지 않은 경로는 모든 필터를 처리한 후에 SecurityContext에 인증 정보가 없으면 예외를 발생시킨다

 

예를 들어 Spring Security와 JWT를 같이 사용하며, 인증 정보가 필요한 리소스에 접근할 때는 HTTP 헤더에 JWT를 전달해야 한다고 가정하자. 그리고 JWT가 헤더에 있는지, 있다면 유효한 토큰인지를 검증하는 JwtFilter가 필터 체인에 등록되어 있다고 가정하자. 

  • permitAll로 설정한 경로 + 잘못된 토큰
    • JwtFilter가 적용된다.
    • JwtFilter에서 토큰 검증을 진행하고, 잘못된 토큰이므로 예외가 발생한다.
    • JwtFilter에서 예외를 잡고, 다음 필터들이 정상 호출된다.
    • permitAll로 설정된 경로이기 때문에 SecurityContext에 인증 정보가 저장되어 있지 않아도 AuthenticationException이 발생하지 않고, 이어서 컨트롤러가 정상 호출된다.
  • permitAll로 설정하지 않은 경로 + 잘못된 토큰
    • JwtFilter가 적용된다.
    • JwtFilter에서 토큰 검증을 진행하고, 잘못된 토큰이므로 예외가 발생한다.
    • JwtFilter에서 예외를 잡고, 다음 필터들이 정상 호출된다. 
    • 그러나 permitAll로 설정된 경로에 접근하려는데 SecurityContext에 인증 정보가 저장되어 있지 않기 때문에 AuthenticationException이 발생한다. 
    • 이때 등록된 AuthenticationEntryPoint 구현체가 호출된다. 이곳에서 원하는 응답을 내려줄 수 있다.
  • permitAll로 설정하지 않은 경로 + 올바른 토큰
    • JwtFilter가 적용된다.
    • JwtFilter에서 토큰 검증을 진행하고, 올바른 토큰이므로 예외가 발생하지 않는다. 그리고 이때 SecurityContext에 Authentication을 저장한다.
    • permitAll로 설정된 경로에 접근하려는데 SecurityContext에 인증 정보가 저장되어 있기 때문에 이어서 정상적으로 컨트롤러가 호출된다.

Reference