java.lang.NullPointerException: Cannot invoke "org.example.springsecuritystudy.repository.JpaTokenRepository.findTokenByIdentifier(String)" because "this.jpaTokenRepository" is null
왜인지 모르겠다..
생성 시 CustomCsrfTokenRepository를 잘 연결한다.
처음에는 @Autowired
문제인 줄 알았는데 POST로 접속하게 되면 정상적으로 로그가 다 찍힌다. 그래서 뭐가 문제인지 찾아보았다.
이 글 마지막에 있는 Spring Security 6 변화점을 통해 힌트를 얻었다. 공식 문서에서 해당 문구를 찾은 결과 아래와 같이 바뀐점을 찾아 볼 수 있었다.
Cross Site Request Forgery (CSRF) :: Spring Security
스프링 시큐리티 6부터는 CsrfToken 의 조회가 필요할 때까지 연기된다. 이는 스프링 시큐리티가 기본적으로 HttpSession 에도 CsrfToken을 저장하기 때문이다. 지연된 CSRF 토큰은 매 요청마다 세션에 요청하지 않음으로써 성능을 향상시킬 수 있다.
만약 지연된 토큰을 먼저 조회하고 싶고 모든 요청에 CsrfToken을 로드하려는 경우 아래와 같이 설정할 수 있다.
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
XorCsrfTokenRequestAttributeHandler requestAttributeHandler = new XorCsrfTokenRequestAttributeHandler();
requestAttributeHandler.setCsrfRequestAttributeName(null);
http
.csrf(c -> c
.csrfTokenRequestHandler(requestAttributeHandler)
.csrfTokenRepository(new CustomCsrfTokenRepository(jpaTokenRepository))
.ignoringRequestMatchers("/ciao")
)
.authorizeHttpRequests(
request -> request.anyRequest()
.permitAll()
);
return http.build();
}
csrfRequestAttributeName
을 null로 설정하면 CsrfToken
이 어떤 속성 이름을 사용할지 결정하기 위해서 처음에 반드시 로딩되어야 한다. 이는 CsrfToken
이 매 요청마다 로딩되도록 한다.
이제 정상적으로 생성되는 것은 확인했다. 하지만 여전히 POST 토큰 값을 함께 보냈을 때 403 Forbidden이 발생했다.
Solving the "Invalid CSRF token found" Error in Spring Security 6.x
좀 더 찾아보니 공식문서에서 사용한 XorCsrfTokenRequestAttributeHandler
대신 CsrfTokenRequestAttributeHandler
를 사용하는 예제를 찾을 수 있었다.
결론적으로 CsrfTokenRequestAttributeHandler
를 사용하니 정상적으로 POST 요청으로 /hello
에 접근할 수 있었다.
XorCsrfTokenRequestAttributeHandler
는 BREACH 보호를 위해 CsrfTokenRequestAttributeHandler
의 하위 클래스다.
Cross Site Request Forgery (CSRF) :: Spring Security
공식 문서에 따르면 매 요청마다 CSRF 토큰 값에 무작위 인코딩을 추가해 변경된 토큰 값을 반환하여 침해를 방지해주는 클래스였다.
성공적으로 POST Hello! 메시지를 받았다!
'Today I Learned' 카테고리의 다른 글
Mermaid ERD 문법 (1) | 2024.12.02 |
---|---|
필터에 @Component 등록 시 자동 등록 (0) | 2024.06.28 |
@Default 빌더 기본값 적용 (0) | 2024.05.28 |