Swagger 로 Spring Security 적용 후 REST API 테스트하던 중 갑자기 403 에러가 식별됐다..

뭐가 문제일까 알아보니.. 스프링시큐리티를 적용하면 기본적으로 보안문제로 인해
CSRF 토큰이 없으면 403에러를 일으킨다고 한다..
기존 코드부터 살펴보자
public SecurityFilterChain exceptionSecurityFilterChain(HttpSecurity http) throws Exception {
http
.sessionManagement((sessionManagement) ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers("/api-docs","/api-docs/json/**", "/swagger-resources/**",
"/swagger-ui/**", "webjars/**","/swagger/**","/sign-api/**").permitAll()
.requestMatchers(HttpMethod.GET,"/product/**").permitAll()
.anyRequest().hasRole("ADMIN")
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class)
);
return http.build();
}
위의 코드를 보면 CSRF 관련 설정값이 없다.
추가해주자.
public SecurityFilterChain exceptionSecurityFilterChain(HttpSecurity http) throws Exception {
http
.sessionManagement((sessionManagement) ->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeRequests((authorizeRequests) ->
authorizeRequests
.requestMatchers("/api-docs","/api-docs/json/**", "/swagger-resources/**",
"/swagger-ui/**", "webjars/**","/swagger/**","/sign-api/**").permitAll()
.requestMatchers(HttpMethod.GET,"/product/**").permitAll()
.anyRequest().hasRole("ADMIN")
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class)
)
// 추가한 부분
.csrf((csrf) -> csrf.requireCsrfProtectionMatcher(new CsrfRequireMatcher()))
.csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()));
return http.build();
}
// 추가한 클래스(swagger일때 토큰 무시)
static class CsrfRequireMatcher implements RequestMatcher {
private static final Pattern ALLOWED_METHODS = Pattern.compile("^(GET|HEAD|POST|TRACE|OPTIONS)$");
@Override
public boolean matches(HttpServletRequest request) {
if (ALLOWED_METHODS.matcher(request.getMethod()).matches())
return false;
final String referer = request.getHeader("Referer");
if (referer != null && referer.contains("/swagger-ui")) {
return false;
}
return true;
}
}
위 코드를 보면 CsrfRequireMather를 만든 이유는 swagger 환경에서 테스트할때는 CSRF 토큰 여부를 체크하지 않기 위해
적용한 것이다.

이제 정상적으로 동작한다.
만약 CSRF 를 전혀 사용하지 않는 환경이라면 위의 코드를 수정하여야 한다.
기존
.csrf((csrf) -> csrf.requireCsrfProtectionMatcher(new CsrfRequireMatcher()))
.csrf((csrf) -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()));
변경
.csrf((csrf) -> csrf.disable());
'Spring' 카테고리의 다른 글
[Spring] Java를 설치해보자(Feat.M1 맥북, Zulu) (1) | 2025.02.14 |
---|---|
[Spring] Swagger 오류(spring.mvc.pathmatch.matching-strategy) (0) | 2025.02.14 |
[Spring] JWT 토큰 에러 (0) | 2025.02.13 |
[Spring] please set 'javax.persistence.jdbc.url', 'hibernate.connection.url', or 'hibernate.dialect' (0) | 2025.02.13 |
[Spring] No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor (0) | 2025.02.13 |