Visual Studio 2022 .NET 9 Blazor Web App で AADSTS50011 を解決する:リダイレクトURIがランダムポートになる原因と対処

Visual Studio 2022(17.12.1)で .NET 9 の Blazor Web App を作り、Microsoft Graph を呼ぶために Entra ID(旧 Azure AD)認証を入れたところ、デバッグ中だけ「redirect_uri のポートが勝手に変わる」せいで AADSTS50011 が出る──そんなハマりどころを、原因の見極め方と実務で効く回避策までまとめます。

目次

起きている現象

典型的な流れは次のとおりです。

  • launchSettings.json で IIS Express の SSL ポート(例:44391)など、ローカルのURLを固定している
  • デバッグ起動すると、アプリ本体は想定どおり https://localhost:44391/ のように固定ポートで開く
  • サインイン操作で別ウィンドウ(Entra ID のログイン画面)へ遷移した瞬間、認証リクエストの redirect_uri に 別のポート番号 が入る
  • App Registration に登録済みのリダイレクトURI(固定ポート)と一致しないため、AADSTS50011(Redirect URI mismatch) で止まる

プロファイル切替や launchSettings.json の作り直し、bin/obj の削除などを試しても改善しないケースがあり、特に VS2022 の .NET 8/Blazor Web App テンプレート由来の挙動が疑われる、という報告もあります。

AADSTS50011 を正しく理解する

AADSTS50011 は、ざっくり言うと「アプリが要求した redirect_uri と、Entra ID の App Registration に登録されている Redirect URI が一致しない」ことを意味します。ここで重要なのは、Entra ID が見ているのは “あなたがブラウザで開いたURL” ではなく、認証要求(authorize)に含まれる redirect_uri パラメーター だという点です。

項目内容ハマりやすい点
redirect_uriログイン後にブラウザが戻ってくる先(コールバックURL)スキーム(http/https)・ホスト・ポート・パスのどれかが違うと不一致になる
登録済み Redirect URIApp Registration 側で許可したコールバックURL一覧登録場所(Web / SPA / Mobile and desktop)を間違えると、登録しているのに不一致扱いになることがある
よくある原因ポート変動、http/https のズレ、末尾スラッシュ違い、パス違いエラー文の redirect_uri を “URLデコード” して、まず実体を確認するのが最短

なぜ「アプリは固定ポートなのに redirect_uri だけランダム」になるのか

OpenID Connect(OIDC)の Web アプリでは、redirect_uri は多くの場合「受け取ったリクエストの Host/Scheme/Port」から組み立てられます。つまり、redirect_uri が想定外になるのは、認証を開始した時点でアプリ(またはミドルウェア)が “別のベースURL” を見ている、ということです。

実務上、疑うべきポイントは次の4つです。

実行プロファイルが想定と違う

Visual Studio のデバッグ対象が IIS Express なのか、プロジェクト直起動(Kestrel、表示上はプロジェクト名)なのかで、URLの決まり方が変わります。画面上は同じ “ローカル起動” に見えても、裏側の実行ホストが違うと port がズレやすくなります。

項目IIS ExpressProject(Kestrel)
ポートの主な決定元launchSettings.json の sslPort、.vs の applicationhost.configlaunchSettings.json の applicationUrl、ASPNETCORE_URLS
変動しやすさ.vs 側の構成が優先されてズレることがあるapplicationUrl を固定していないと変動しやすい
確認の近道出力ウィンドウより、ブラウザのURLと IIS Express の設定を照合出力ウィンドウの「Now listening on:」のURLを確認

http と https のどちらで認証要求が組み立てられているかが違う

「ポートが変わっている」ように見えて、実は http 側のポート を使っているだけ、というケースがあります。IIS Express は http と https を別ポートで持つことが多く、sslPort(https)を固定していても、http 側がランダムなままだと、認証要求が http 側で組み立てられてズレることがあります。

App Registration のプラットフォーム設定が合っていない

Blazor Web App(.NET 8/9 の統合テンプレート)は、構成次第で「サーバー側の OIDC(Web)」と「クライアント側(SPA)」が混在して見えます。実際に使っているフローに対して、App Registration の Redirect URI を “適切なプラットフォーム” に登録できていないと、登録しているのに一致しない、という現象が起きます。

テンプレート/ツール側の癖で、デバッグ時だけ別URLが使われる

スレッド内でも示唆されているとおり、VS2022 の .NET 8/Blazor Web App テンプレート特有の挙動として疑われるケースがあります。この場合、設定ファイルだけを直しても変化がなく、「開発時はポート変動を許容する」 方向に寄せる方が早く安定します。

解決策:localhost は「ポートなし Redirect URI」を登録して吸収する

受理された回答の要点はシンプルで、開発環境(localhost)では、Redirect URI にポート番号を固定で入れない という運用に寄せる、というものです。Entra ID 側に “ポートを省略した localhost の URI” を追加登録しておくことで、デバッグ時にポートが変動しても許容できるケースがあります。

登録例(回答で挙げられていたパターン)

用途登録例意図
サインインのコールバックhttp://localhost/signin-oidc
https://localhost/signin-oidc
ポート変動を吸収しつつ、OIDC の標準コールバックパスを許可する
ルートや任意ページhttps://localhost/
https://localhost/home
テンプレートや実装によって戻り先が変わる場合に備える

ポイントは「localhost に限って」という点です。プロダクションのドメインでポート省略=どのポートでも良い、という設定は基本的にできませんし、セキュリティ上も推奨されません。あくまで開発時の互換性を上げるための割り切りです。

Entra ID 側の追加登録手順

  1. Entra 管理センター(または Azure Portal)で App registrations を開く
  2. 対象アプリを選び、Authentication を開く
  3. プラットフォームが Web(サーバー側 OIDC)であることを確認する
  4. Redirect URIs に、ポートを省略した localhost のURIを追加する
  5. 保存後、デバッグ実行して AADSTS50011 が解消するか確認する

この方法が効くときの判断基準

次の条件に当てはまる場合は、この回避策が刺さりやすいです。

  • ローカル開発のみで起きており、ステージング/本番では固定ドメインで運用している
  • 実行プロファイルやツール更新でポートが変わりやすい(チーム開発、複数プロジェクト、複数ブランチなど)
  • 短期的に “認証が動く状態” を優先したい(原因追跡は後回しでも良い)

注意:この方法だけでは解決しないケースもある

同スレッド内では、「ポートなし登録では解決しない」 という報告もありました。つまり、今回の現象は「単なるポート変動」だけでなく、テンプレートやプロファイル、http/https の混在など、別の不一致が潜んでいる可能性があります。

そこでここからは、現場で再現性高く切り分けるためのチェックポイントを、優先度順に整理します。

チェックポイント:まずは “実際に送られた redirect_uri” を見る

最短で原因を絞るなら、エラー画面に出ている redirect_uri をそのまま信じるのではなく、authorize リクエストのURL を開いて確認します。

  1. サインインを押して Entra ID のログイン画面へ飛ぶ
  2. ブラウザのアドレスバーにあるURL(login.microsoftonline.com へ向いている長いURL)をコピーする
  3. URL 内の redirect_uri= を探し、値を URL デコードして “人間が読めるURL” にする

見たいのは、次のような形になっている部分です。

redirect_uri=https%3A%2F%2Flocalhost%3A51567%2Fsignin-oidc

ここで初めて、「ポートが違う」のか「http になっている」のか「パスが違う(/signin-oidc ではない)」のかが確定します。確定したら、対処はほぼ自動的に決まります。

チェックポイント:ホスティング形態と Redirect URI の対応を合わせる

Blazor Web App で Microsoft.Identity.Web(OIDC)を使う場合、典型的なコールバックパスは /signin-oidc です。まずは “どのURLで動いているか” と “どのURLを登録しているか” を表で突き合わせます。

デバッグ実行の実態アプリが待ち受けているURL例App Registration に登録する例
IIS Express(https を使用)https://localhost:44391/https://localhost:44391/signin-oidc
IIS Express(http で要求が出ている)http://localhost:12345/http://localhost:12345/signin-oidc
Project(Kestrel)https://localhost:7001/https://localhost:7001/signin-oidc
開発時の互換性重視(ポートが変わる)https://localhost/signin-oidc など

「アプリ本体を開くURL」と「redirect_uri」は別物ではありません。Web アプリの OIDC では、その瞬間のホスト情報から組み立てられるため、実体がズレているなら、どこかでホスト情報がズレています。

チェックポイント:launchSettings.json の “見た目” と “実際の優先順位” を確認する

固定ポートを指定したつもりでも、実際には別設定に上書きされていることがあります。特に IIS Express は、ソリューション配下の .vs フォルダーにある構成(applicationhost.config)が絡むため、launchSettings.json だけ見ても決め打ちできません。

launchSettings.json の例(ポイントだけ)

{
  "iisSettings": {
    "iisExpress": {
      "applicationUrl": "http://localhost:12345",
      "sslPort": 44391
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress"
    },
    "MyApp": {
      "commandName": "Project",
      "applicationUrl": "https://localhost:7001;http://localhost:5001"
    }
  }
}
  • IIS Express の sslPort を固定しているのに redirect_uri が別ポートなら、まず「本当に IIS Express で動いているか」を疑います。
  • Project プロファイルが選ばれていると、applicationUrl 側が使われます。ここが別ポートなら、それが redirect_uri に出るのは自然です。
  • http/https が混在していると、どちらで認証が始まったかで redirect_uri も変わります。

実務では次の順で確認すると早いです。

  1. Visual Studio のツールバーで、デバッグターゲットが IIS Express か Project かを確認する
  2. デバッグ出力に表示される待ち受けURL(Now listening on)を確認する
  3. authorize URL の redirect_uri を確認し、どの待ち受けURLと同じ系統か照合する

チェックポイント:.vs フォルダーを含めた “デバッグ環境のキャッシュ” を疑う

bin/obj を消しても直らない場合、次に疑うのは .vs(隠しフォルダー)です。ここには IIS Express のポート設定やユーザーごとのキャッシュが入っており、チームで共有しない前提のものが混ざっています。

  • ソリューション直下の .vs フォルダーを閉じてから削除(またはリネーム)
  • Visual Studio を再起動
  • IIS Express のポートが再生成されるので、改めて redirect_uri を確認

“固定したはずの sslPort が違う” “いつの間にか http ポートが変わった” といった揺れがある場合、この作業で整うことがあります。

どうしても固定ポートに寄せたい場合の現実的な落としどころ

開発環境でも「絶対にこのポートでないと困る」という事情がある場合は、以下のどちらかに寄せるのが現実的です。

固定ポートを維持し、App Registration を “固定ポートで厳密に合わせる”

  • デバッグターゲットを 1つに決める(IIS Express なら IIS Express に統一)
  • http/https を混在させない(https に寄せる)
  • Entra ID の Redirect URI に、実際に送られている redirect_uri と完全一致 するものを登録する

ポート変動を許容し、App Registration を “localhost は緩く” する

  • チーム開発や複数プロジェクトでポート衝突が起きやすいなら、こちらが運用しやすい
  • 本番環境は固定ドメインで厳密運用、開発だけ緩める、という分離がしやすい

それでも直らないときの最終手段

根本原因の追跡を後回しにして、とにかく開発を進めるための “暫定策” もあります。OpenID Connect のリダイレクトを組み立てるタイミングで、redirect_uri を明示的に上書きする方法です。

ただしこの方法は、上書きしたURLに本当にアプリが戻ってこられることが前提です。ポート変動を許容したいのに固定ポートへ上書きすると、今度は “戻り先に接続できない” で失敗します。用途は「固定ポートに統一したいのに、なぜか違うポートで組み立てられる」場合に限ってください。

// 例:OpenID Connect の redirect_uri を固定する(開発用の暫定策)
using Microsoft.AspNetCore.Authentication.OpenIdConnect;

builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Events.OnRedirectToIdentityProvider = context =>
    {
        context.ProtocolMessage.RedirectUri = "https://localhost:44391/signin-oidc";
        return Task.CompletedTask;
    };
});

環境ごとに切り替えるなら、固定値を直書きせず、appsettings.Development.json や環境変数に逃がすのが安全です。

開発と本番を事故らせないためのおすすめ設計

今回のような redirect_uri 問題は、実は「開発環境の利便性」と「本番環境の厳密さ」が衝突した結果でもあります。運用としては次が安定します。

  • Entra ID の App Registration を 環境で分ける(少なくとも Dev と Prod を分ける)
  • Dev は localhost 前提で柔軟に(ポートなし登録を許容する、または複数ポートを登録する)
  • Prod は固定ドメイン+https のみ、Redirect URI は最小限に絞る
  • Graph の権限(Scopes)やリダイレクトURIを変更したら、必ず “実際の authorize URL” で差分確認する

まとめ

  • AADSTS50011 は「App Registration に登録した Redirect URI」と「実際に送った redirect_uri」の不一致で起きる
  • まず authorize URL の redirect_uri を URL デコードして、何が違うのか(ポート・http/https・パス)を確定させる
  • 開発環境(localhost)では、ポートなしの Redirect URI を追加登録してポート変動を吸収する、という回避策がある
  • 解決しない場合は、プロファイル/http/https/プラットフォーム登録場所/.vs のキャッシュを重点的に疑う

一度 “どのURLがどの設定で決まるか” を整理すると、Blazor Web App+Entra ID 認証のデバッグは格段に楽になります。チーム開発では、Dev 用 App Registration を切り出して、localhost を柔軟に扱う方針に寄せるのが現実的です。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次