0
0

Spring Security でログイン後にCSRFトークンがCookieに設定されない問題への対処方

Last updated at Posted at 2024-08-17

はじめに

Spring Security でCookieによるCSRF対策を実施している場合、クライアント側ではCookieの"XSRF-TOKEN"を読み取ります。
しかし、ログイン認証処理後やログアウト後は、Cookieがクリアされてしまいます。
それにより、ログイン後にCookieを取得することが出来なく、処理を続行することができません。
デフォルトの設定だとうまくいきませんのでひと工夫が必要です。

解決策

解決策は、公式サイトに書いてあります。
https://spring.pleiades.io/spring-security/reference/servlet/exploits/csrf.html#csrf-integration-javascript-spa

CookieにCSRFトークンを出力するためのフィルタを新たに作成
※公式サイトより一部引用

新たに作成するFilter
final class CsrfCookieFilter extends OncePerRequestFilter {

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		CsrfToken csrfToken = (CsrfToken) request.getAttribute("_csrf");
		// Render the token value to a cookie by causing the deferred token to be loaded
		csrfToken.getToken();

		filterChain.doFilter(request, response);
	}
}

上記クラスをSecurityConfigに追加

SecurityConfig

@Configuration
@EnableWebSecurity
public class SecurityConfig {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		http
			// ...
			.csrf((csrf) -> csrf
				.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())   
				// ...
			)
			.addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class); // 新たに作成したFilterを追加
		return http.build();
	}
}

これにより、ログイン後やログアウト後にもCSRFトークンがCookieに設定されるようになります。

最後に

Spring SecurityのCSRF対策機能では、シングルページアプリケーションやRestAPIの場合、Cookieを利用してCSRF対策を行うことが必須となりますが、ここで述べた問題だけでなく、シングルページアプリケーションやRestAPIにおけるSpring Security でのCSRF対策でも述べた問題もあり、デフォルトの状態だと動かなかったりします。
前述の通り公式サイトに書いてはいるのですが、それ以外にはなかなか情報がなかったため、こちらに記載しました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0