intro
- 프로젝트를 진행하며 발생한 문제 상황과 해결 과정들을 상세히 기록하고 추후에 같은 문제가 발생 했을때 빠르게 문제 해결하기 위해 트러블 슈팅을 정리할려고 한다.
- 기록하는 습관을 기르기 위해 프로젝트 기간동안 꾸준히 작성할 것 이다.
⚠️ 1.문제 상황 발생
Spring Security로 회원가입 API를 만들고 Postman으로 테스트를 하던 중, 다음과 같은 설정에도 불구하고 401 Unauthorized가 발생했다.
http.authorizeHttpRequests((auth)->auth
.requestMatchers("/", "/login", "/users/signup").permitAll()
.requestMatchers("/admin").hasRole("ADMIN")
.requestMatchers("/my/**").hasAnyRole("ADMIN","USER")
.anyRequest().authenticated()
);
Postman에서 /users/signup로 Post 를 요청 했지만
😵 로그인도 안 필요하다며… 왜 막는 거야?
🔎 2.원인 추론
처음엔 "내가 권한 설정을 잘못했나?" 하고 봤지만, 아래와 같이 /users/signup 경로는 분명히 누구나 접근 가능하게 열어둔 상태였다.
http
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "/login", "/users/signup").permitAll()
.anyRequest().authenticated()
);
게다가 인증이 아예 안 된 경우는 보통 401 Unauthorized가 나와야 정상이지만, 지금은 403 Forbidden.
즉, "로그인은 필요 없지만, 뭔가 조건이 충족되지 않아서 차단" 당한 상황이었다.
찾아보니 Spring Security는 기본적으로 CSRF(Cross Site Request Forgery) 보호가 활성화되어 있다.
이 보호 기능은 브라우저 환경에서 폼을 통해 요청을 보낼 때는 유효하지만, Postman이나 외부 앱에서 토큰 없이 보내는 요청은 CSRF 공격으로 간주하고 차단해버린다.
즉, 아무리 permitAll()을 해놔도 CSRF 토큰이 없으면 POST 요청 자체를 거부하는 것이다.
📝 3.해결방안
테스트 단계나 외부 도구(Postman 등)로 API를 테스트할 때는 아래처럼 CSRF 보호를 꺼주면 된다.
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests((auth) -> auth
.requestMatchers("/", "/login", "/users/signup").permitAll()
.anyRequest().authenticated()
);
CSRF 가 무엇인지 간단히 살펴보자.
ㅍ
✅ CSRF란?
- 사용자가 의도하지 않은 요청을 보내게 만드는 공격
- 브라우저 환경에서 로그인된 세션 쿠키를 악용해 요청을 보내는 방식
- 그래서 Spring Security는 기본적으로 POST/PUT/DELETE 요청에는 CSRF 토큰을 요구함
📌4.결과 확인
정상적으로 200 OK 응답했다.
✒️회고
- Spring Security에서 POST 요청이 403이 난다고 해서 무조건 권한 문제는 아니다.
- 특히 Postman이나 외부 클라이언트에서 테스트할 땐 CSRF 설정 여부를 꼭 확인하자.
'프로젝트 > 트러블슈팅' 카테고리의 다른 글
[Spring]무한 스크롤 + Enum 정렬 트러블슈팅 (2) | 2025.04.23 |
---|---|
[Spring]Filter 예외처리 (0) | 2025.04.03 |
[JAVA]Enum 에 선언된 메소드 호출오류 (0) | 2025.03.13 |
[JAVA]리스트 초기화 오류 (1) | 2025.03.05 |
[JAVA]입력 버퍼비우기 - (Next() , NextLine()) (0) | 2025.03.05 |