본문 바로가기
프로젝트/AnswerDev

[AnswerDev] 3. Security 필터와 permitAll()

by kim-dev 2024. 8. 17.
반응형

 

대충 Jwt 인증 필터를 구현했다.
Role은 크게 필요성을 느끼지 못 해서, 인가 필터는 따로 구현하지 않았다.

 

이후 내가 작성한 JwtAuthenticationFilter을 UsernamePasswordAuthenticationFilter 직전에 거치도록 해 주었다.
여기서 UsernamePasswordAuthenticationFilter은 Spring Security가 기본적으로 인증된 요청인지 검사할 때 사용하는 필터라서, 커스텀 인증 필터를 구현할 땐 해당 필터 앞에 거치도록 만들어주면 된다.

// SecurityConfig.java

@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
    httpSecurity

            ...

            // URL 별로 권한을 설정
            .authorizeHttpRequests((authorize) -> {
                authorize
                        .requestMatchers( "/user/login", "/user/login").permitAll()
                        .anyRequest().authenticated();
                // requestMatchers("/user").hasRole("USER") // USER 권한이 있는 유저만 접근 가능
            })

            .addFilterBefore(new JwtAuthenticationFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class);

    return httpSecurity.build();
}

 

SecurityConfig를 이렇게 작성해 주고, 이제 /user/login과 /user/signup을 제외한 다른 모든 요청은 모두 JwtAuthenticationFilter을 거치도록 해 주었다

 

...라고 생각했었는데, 분명 permitAll()을 적용한 /user/login과 /user/signup에도 해당 인증 필터가 적용이 되어서 토큰이 필요하다고 응답하는 것이었다.

 

뭐지? permitAll()을 적용하면 해당 엔드포인트는 인증이 필요하지 않게 되어 UsernamePasswordAuthenticationFilter을 거치지 않는 게 아닌가??

 

결론은 그게 아니었다.
permitAll()을 적용해도 설정되어 있는 모든 필터는 거친다. 단지 서버의 리소스에 접근할 때, 인증이 없어도 접근을 허용해주겠다는 의미였다.
이미 나는 인증 필터를 적용해 놨기 때문에, permitAll()을 해봤자 큰 의미는 없었던 것...

 

그래서 내가 작성한 인증 필터인 JwtAuthenticationFilter에 아래 부분을 추가해 주었다.

@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
    String path = request.getRequestURI();
    return path.startsWith("/user/login") || path.startsWith("/user/signup");
}

shouldNotFilter 메서드는 OncePerRequestFilter을 상속받은 필터라면 오버라이드 할 수 있는 메서드로, 해당 필터를 거치는 모든 요청은 이 메서드를 거친다. 여기서 true를 반환하는 엔드포인트라면 필터를 거치지 않도록 하는 용도이다.

 

결국 이렇게 작성해 주니 내가 의도한 대로 회원가입과 로그인 요청에는 필터를 거치지 않게 동작하였다.
...그러면 결국 permitAll()은 아무 의미가 없는 건가? 이 부분은 좀 더 공부를 해 봐야겠다.