JWT 利用時の 401 と 403 は意味が違う。401 は「認証できていない」、403 は「認証はできたが許可されていない」が基本。
先に結論
- 401 … トークン無し・不正・期限切れ・署名検証失敗
- 403 … トークンは通ったがロール/ポリシー不足
- まず Authorization ヘッダ(Bearer)の有無と中身を確認
- Authority / Audience / 署名鍵(または JWKS)の設定ずれが多い
401 のチェック
Authorization: Bearer ... が付いているか
- トークンの
exp(期限)とサーバ時刻ずれ
iss / aud が設定の ValidIssuer / ValidAudience と一致するか
- 署名アルゴリズムと鍵(対称鍵 or 公開鍵)が環境と一致するか
- メタデータアドレス(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 はロール/ポリシーとクレームの突合
関連記事