zukucode
主にWEB関連の情報を技術メモとして発信しています。

ASP.NET SPAサイトでログイン認証後に400エラーになるときの対処法

ASP.NETのSPAプロジェクトでログイン認証後にCSRFエラーになるときの対処法を紹介します。

以下の2つのページの処理(CSRF保護と認証保護)を実装したとき、ログイン処理とログアウト処理のあとのリクエストが400エラーになることがあります。

原因はCSRF保護によるエラーです。(この原因がわかるまで1日かかりました。。)

対処法

ログイン(ログアウト)認証をしたあとはXSRF-TOKENトークンを再発行する必要があります。

ASP.NET SPAサイトにcookieベースのログイン認証を実装するで作成した認証用のコントローラーにXSRF-TOKENトークンを再発行する処理を追加します。

using Microsoft.AspNetCore.Antiforgery;

namespace code.Controllers
{
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class AuthController : ControllerBase
    {
        private readonly IAntiforgery _antiforgery;

        public AuthController(IAntiforgery antiforgery)
        {
            _antiforgery = antiforgery;
        }

        private void RefreshXsrfToken()
        {
            // XSRF-TOKENを再発行
            var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
            HttpContext.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, 
                new CookieOptions() {
                    HttpOnly = false,
                    Secure = true
                });
        }

ログイン(ログアウト)認証後にXSRF-TOKENを再発行する処理を追加します。

// ログイン
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);

HttpContext.User = claimsPrincipal;
RefreshXsrfToken();

// ログアウト
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

HttpContext.User = new ClaimsPrincipal();
RefreshXsrfToken();

関連記事