🦁

AllowAnonymousの注意点

2024/01/19に公開

AuthorizeとAllowAnonymous

こんにちは。
今日は実務で遭遇したエラーについて投稿します。

500エラーの経緯

遭遇したエラーは、単なる500エラー(Internal Server Error)なのですが、
意外と単純なミスで起きたものでした。
発生フローは以下です。

  1. appsetting.jsonに設定したセッションタイムアウトが経過
  2. クライアントからAjaxでサーバーにGETリクエストを送信
  3. Startup.csの認証ミドルウェアをリクエストが通過
  4. Controllerのアクションメソッドでリクエストを受け取る
  5. アクションメソッド内のユーザー情報を取得する処理でstatus code 500エラー

通常は3.の認証ミドルウェアでクライアントに401エラー(認証エラー)を返すので、
サーバーまでリクエストは到達しないのですが、この処理だけ到達していました。

500エラーの正体

Controllerの処理を見ていると共通点が見えてきました。
Controllerのメソッド指定を見てみると、このエラーが起きている全てのメソッドに
AllowAnonymousが指定されていました。

[HttpGet]
[AllowAnonymous]
public IActionResult GetPassword(GetPasswordViewModel vm)
{
   var userNo = HttpContext.User.Identity.UserNo();
   var loginUserInfo = bus.Handle(new AccountGetLoginUserInfoInputData(userNo));
   vm.UserID = loginUserInfo.UserId;
   ModelState.Clear();
   return View(vm);
}

通常、セッションタイムアウトが起きるとユーザー情報は失われるので、
このアクションに入っても、

var userNo = HttpContext.User.Identity.UserNo();

の部分でユーザー情報が取得できないので、エラーになります。

AllowAnonymousとは

公式ドキュメントによると、認証されていないユーザーによるアクションへのアクセスを許可できる属性とあります。
https://learn.microsoft.com/ja-jp/aspnet/core/security/authorization/simple?view=aspnetcore-8.0

ログイン処理では、ログイン時点でユーザー未認証なのでこの属性は設定する必要があります。

解決策

ログイン以降はセッションタイムアウトなどでユーザー情報が失われる可能性もあるので、
基本的に[Authorize]属性を使用することで認証済みユーザーだけアクセスできるようにしましょう。

[HttpGet]
[AllowAnonymous]
public IActionResult GetPassword(GetPasswordViewModel vm)
{
   //free
}

Discussion