• システム開発に関わる内容をざっくりと書いていく

JWT 認証 401 / 403 の切り分け(ASP.NET Core)

JWT 利用時の 401 と 403 は意味が違う。401 は「認証できていない」、403 は「認証はできたが許可されていない」が基本。

先に結論

  • 401 … トークン無し・不正・期限切れ・署名検証失敗
  • 403 … トークンは通ったがロール/ポリシー不足
  • まず Authorization ヘッダ(Bearer)の有無と中身を確認
  • Authority / Audience / 署名鍵(または JWKS)の設定ずれが多い

401 のチェック

  1. Authorization: Bearer ... が付いているか
  2. トークンの exp(期限)とサーバ時刻ずれ
  3. iss / aud が設定の ValidIssuer / ValidAudience と一致するか
  4. 署名アルゴリズムと鍵(対称鍵 or 公開鍵)が環境と一致するか
  5. メタデータアドレス(OpenID)が到達できるか

403 のチェック

  • [Authorize(Roles = "...")] やポリシーの要求とクレームが一致するか
  • ロールクレームの種類名(role / roles)のマッピング
  • エンドポイントごとの AllowAnonymous の有無
  • 認証は成功しているのに認可ミドルウェアで落ちていないか

ログで見ると早い点

  • Authentication の失敗理由(期限・audience・署名)
  • 認証後の User.Claims 一覧(開発時のみ)
  • ミドルウェア順(Authentication → Authorization)
builder.Services.AddAuthentication().AddJwtBearer(o =>
{
    o.Authority = "...";
    o.Audience = "...";
    // 失敗理由をログするイベントを足すと切り分けが速い
});

ざっくりまとめ

  • 401=認証、403=認可、を先に分ける
  • Bearer・iss/aud・鍵・期限を順に確認
  • 403 はロール/ポリシーとクレームの突合

関連記事