ASP.NET Core 8(Razor Pages)で Identity を追加すると、ログインや登録などの既定 UI が /Identity/Account/... 配下に出てきます。ところが「テストのために / 配下(例:/Account/Login)へ移したい」と思っても、MapIdentityApi を追加するだけでは変わりません。本記事では、変わらない理由と、現実的に URL を変える手順を具体例つきで整理します。
結論:既定の Identity UI を「/Identity → /」へ一括で移す設定は用意されていない
最初に結論です。ASP.NET Core の「既定の Identity UI(ログイン/登録/管理画面など)」は Razor Pages として Identity エリアに組み込まれており、URL の先頭に付く /Identity は基本的に“そういう設計”です。アプリ設定を少し変えるだけで /Identity を / に差し替える、といった仕組みは提供されていません。
そして、質問にある app.MapGroup("/").MapIdentityApi<IdentityUser>(); は「画面 UI の URL を変える」ためのものではありません。これは主に Identity の API エンドポイント(最小 API)を生やすためのマッピングで、Razor Pages の既定 UI のルーティングには効きません。
では URL を変えたい場合、現実的な選択肢は次の 2 つです。
- 追加ルート(別名ルート)を用意する:
/Account/Loginでも既定 UI を開けるようにする(最短でテストしたい方向け) - Identity ページをスキャフォールディングして取り込み、ルートを自分で管理する:ファイルとしてプロジェクト側へ生成し、
@pageなどを編集して希望のパスにする(長期運用/本番向け)
なぜ /Identity 配下になるのか(Identity エリアと Razor Pages の規約)
Razor Pages は基本的に「ファイルの場所 → URL」という対応でルーティングされます。既定の Identity UI は、内部的に Areas/Identity/Pages/Account/Login.cshtml のような場所にある Razor Pages として提供されます。
ここで重要なのが Areas(エリア)です。Area 名が Identity なので、URL も規約に従って /Identity/Account/Login のようになります。つまり、/Identity は “たまたま付いている” のではなく、「Area が Identity である」ことの結果です。
| 要素 | 既定 Identity UI の実体 | URL が決まる理由 |
|---|---|---|
| UI(画面) | Razor Pages(Area: Identity) | ファイルパス規約+Area 規約で /Identity が先頭に付く |
| API(エンドポイント) | 最小 API の Identity エンドポイント | MapIdentityApi / MapGroup などで prefix を付けて管理できる |
MapIdentityApi で URL が変わらない理由(UI と API は別物)
MapIdentityApi は “ログイン画面を /Account/Login にする” といった UI の都合ではなく、SPA やモバイルクライアントなどから叩きやすい API エンドポイント群を追加するための仕組みです。MapGroup("/account") のように prefix を付ければ /account/login などにできますが、これは「API の話」であって「Razor Pages UI の話」ではありません。
そのため、既定 UI(/Identity/Account/Login など)を “まとめて” 動かしたい場合に、MapIdentityApi をどこに追加しても効果がありません。UI は Razor Pages の仕組みで動いているからです。
対応策A:追加ルートで /Account/… を生やす(最短でテストしたい人向け)
「既定 UI のコードは触りたくないけど、/Account/Login みたいな URL でも開けるようにしたい」なら、この方法が一番ラクです。既定の Identity UI はそのままに、別名ルート(追加ルート)を付けます。
追加ルートの例(Program.cs)
Razor Pages の規約(Conventions)で、Area ページに別ルートを追加できます。
using Microsoft.AspNetCore.Identity;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(options =>
{
// 既定 UI のページに別ルートを追加する
options.Conventions.AddAreaPageRoute("Identity", "/Account/Login", "/Account/Login");
options.Conventions.AddAreaPageRoute("Identity", "/Account/Register", "/Account/Register");
options.Conventions.AddAreaPageRoute("Identity", "/Account/Logout", "/Account/Logout");
options.Conventions.AddAreaPageRoute("Identity", "/Account/AccessDenied", "/Account/AccessDenied");
// 管理画面(例:パスワード変更)も寄せたいなら必要に応じて追加
options.Conventions.AddAreaPageRoute("Identity", "/Account/Manage/Index", "/Account/Manage");
});
builder.Services.AddDefaultIdentity<IdentityUser>()
.AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
これで、たとえば /Account/Login でもログイン画面が開けるようになります(中身は既定 UI の同じページです)。
追加ルート方式のメリット/デメリット
| 観点 | メリット | デメリット |
|---|---|---|
| 実装コスト | 最小。既定 UI を生成せずに済む | ページ単位でルート追加が必要(「丸ごと一括」はやりにくい) |
| 保守 | 既定 UI のアップデートに追従しやすい | URL の正規化(旧 /Identity をどう扱うか)を別途考える必要 |
| URL 変更の徹底 | /Account でも動く | /Identity も引き続き生きる(必要ならリダイレクト設計が必要) |
(重要)Cookie の LoginPath/LogoutPath も合わせる
URL を変えたのに、認可がかかったページへ行くと変な場所に飛ぶ(または /Identity/Account/Login に戻る)ケースの多くは、Cookie 認証のリダイレクト先が古いままです。LoginPath / LogoutPath / AccessDeniedPath を新しい URL に揃えてください。
builder.Services.ConfigureApplicationCookie(options =>
{
options.LoginPath = "/Account/Login";
options.LogoutPath = "/Account/Logout";
options.AccessDeniedPath = "/Account/AccessDenied";
});
| 設定項目 | 役割 | おすすめ設定例 |
|---|---|---|
| LoginPath | [Authorize] で未ログイン時に飛ぶ先 | /Account/Login |
| LogoutPath | ログアウトの既定パス(UI と合わせる) | /Account/Logout |
| AccessDeniedPath | 権限不足時の遷移先 | /Account/AccessDenied |
リンク生成も見直す(_LoginPartial など)
既定テンプレートや既定 UI が出すリンクは asp-area="Identity" を含むことがあります。追加ルートを作っても、リンクが旧 URL を指し続けると「結局 /Identity に遷移してしまう」ため、ナビゲーションのリンクを新 URL に合わせましょう。
例:_LoginPartial.cshtml にこういうリンクがあるなら、asp-area を外して新パスへ寄せます。
<!-- 変更前(既定) -->
<a asp-area="Identity" asp-page="/Account/Login">Login</a>
<!-- 変更後(/Account/Login を正規ルートにしたい) -->
<a asp-page="/Account/Login">Login</a>
旧 /Identity を新 URL に寄せたい場合(リダイレクト)
テスト環境でも「URL が二重に存在するのは気持ち悪い」という場合は、/Identity/Account/Login → /Account/Login のように 301/302 リダイレクトを入れる選択もあります。ASP.NET Core の URL Rewriting を使うか、アプリのルーティング設計として “旧パスは案内だけ残す” など、目的に合わせて調整します(本番公開するなら 301 の扱いも含めて慎重に)。
対応策B:Identity ページをスキャフォールディングして “本当に” / 配下で管理する(推奨)
URL を本格的に変えたい、画面もカスタムしたい、今後の要件変更に備えたいならこちらです。既定の Identity UI を プロジェクトに生成(スキャフォールディング)して取り込み、あなたのコードとしてルーティングを管理します。
スキャフォールディング手順(Visual Studio の場合)
- ソリューションエクスプローラーでプロジェクトを右クリック
- [追加]→[新しいスキャフォールディング アイテム]
- [Identity]を選択し、必要なページ(Login/Register/Manage など)を選ぶ
- 既存の
DbContext(例:ApplicationDbContext)を指定して生成
Visual Studio 以外(VS Code など)で CLI から行う場合は dotnet-aspnet-codegenerator を使います。
生成されたファイルの見え方
生成すると、プロジェクト内に Areas/Identity/Pages/Account や Areas/Identity/Pages/Account/Manage などが作られ、これまで “見えなかった” 既定 UI の実体がファイルとして現れます。ここからが自由に変更できる世界です。
ルートを /Account/… に変える実装パターン
スキャフォールディング後、URL を /Identity から外すには代表的に次の 2 パターンがあります。
| パターン | やり方 | 向いているケース | 注意点 |
|---|---|---|---|
| ページ側で絶対ルート指定 | @page "/Account/Login" のようにテンプレートを指定 | 最小差分で URL だけ変えたい | 既存ルートとの共存/移行設計を意識する |
| Pages 配下へ移設 | Areas/Identity から Pages/Account へ移して通常ページ化 | “Identity エリア” から卒業して自分の構成に統合したい | 名前空間や参照、リンクを広めに直す必要が出やすい |
パターン1:@page で絶対ルートを指定する(例:Login)
たとえば Areas/Identity/Pages/Account/Login.cshtml を開き、先頭の @page を次のように変更します。
@page "/Account/Login"
@model LoginModel
@{
ViewData["Title"] = "Log in";
}
Register/Logout/AccessDenied なども同様に揃えていきます。「ファイルの配置は Area のまま」でも、URL の入口は /Account/Login にできます。
ただし、既存の /Identity/Account/Login を完全に消すのか、移行期間だけ残すのかは方針を決めてください。完全に消すなら、旧 URL にアクセスしてきたユーザー(ブックマーク等)への対応としてリダイレクトや案内ページを用意するのが安全です。
パターン2:Pages/Account へ移設して “ふつうの Razor Pages” にする
既定 UI を自分のページ構成へ馴染ませたい場合は、Pages/Account フォルダを作り、必要なページを移動させます。移動後はファイルパス規約に従って /Account/Login になり、Area の概念から切り離せます。
この場合、ページモデル(.cshtml.cs)の名前空間や、ビュー側の @namespace/@addTagHelper などに影響が出ることがあります。移動したページがビルドエラーになるときは、まずは次を確認してください。
- ページモデルの
namespaceが移動先に合っているか Pages/_ViewImports.cshtmlに必要な TagHelper が入っているかasp-area="Identity"が残っていないか(残っていると旧 URL を生成しがち)
(重要)Cookie 設定は“必ず”新 URL と一致させる
URL だけ変えても、未認証時の自動リダイレクトは Cookie 認証の設定が握っています。Identity を使う場合でも、結局は Cookie 認証が「ログイン先はどこか」を知っている必要があります。Microsoft のドキュメントでも ConfigureApplicationCookie による LoginPath 指定が例示されています。
builder.Services.ConfigureApplicationCookie(options =>
{
// あなたが正規ルートにしたいログイン/ログアウト先へ
options.LoginPath = "/Account/Login";
options.LogoutPath = "/Account/Logout";
options.AccessDeniedPath = "/Account/AccessDenied";
// 必要なら Cookie 名や有効期限もここで
// options.Cookie.Name = "YourAppAuth";
// options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
});
ここを忘れると、次のような症状になりがちです。
[Authorize]を付けたページへ行くと、意図しない/Identity/Account/Loginに飛ぶ- ログイン後に ReturnUrl へ戻れず、ループする
- ログアウト後の遷移が 404 になる
リンク生成と ReturnUrl の落とし穴
Identity UI は「ログイン成功後に元のページへ戻す」ために ReturnUrl を使います。URL を変えるときは、次の 2 点を特に意識すると事故が減ります。
- リンク生成の統一:画面内リンク(ヘッダー、フッター、ボタン)が新 URL を生成するように揃える
- ReturnUrl の受け渡し:ログイン画面へ飛ばす時に
?ReturnUrl=...が維持されるようにする
たとえば、ログインへ誘導するリンクを自作する場合は、ReturnUrl を付与しておくと UX が安定します(例:ログイン後に “さっき見ていたページ” に戻す)。
<a asp-page="/Account/Login"
asp-route-returnUrl="@[email protected]">
ログイン
</a>
もちろん要件次第で “常にトップへ戻す” などもアリですが、テスト段階でも ReturnUrl を雑に扱うと「ログインできたのに戻れない」が起きやすいので、早めに方針を決めるのがおすすめです。
よくある質問
UseAuthorization() の後に MapIdentityApi を置けば変わる?
変わりません。MapIdentityApi が追加するのは API エンドポイントで、Razor Pages の既定 UI(/Identity/Account/...)のルーティングには影響しないためです。
“/Identity をまとめて / に” は本当に無理?
「設定 1 行で一括置換」みたいな方法は用意されていません。実現したいなら、結局は ページをスキャフォールディングしてルーティングを編集するのが王道です。Microsoft の Q&A でも “ハードコードされているためスキャフォールディングして変更が必要” という趣旨の回答が示されています。
追加ルート方式だと /Identity が残るのが気になる
気になる場合は、旧パスを新パスへリダイレクトする設計にします。テスト環境なら 302 で十分なことも多いですし、本番なら SEO やキャッシュ影響も見て 301 を検討します。いずれにせよ「旧 URL へ来た人をどうするか」を決めるのがポイントです。
Identity API(MapIdentityApi)はいつ使う?
Razor Pages の画面を使わず、SPA やモバイルアプリから API として登録/ログインを行いたい場合に有効です。UI を URL ごとカスタムしたい要件とは別軸なので、「画面の URL を変えたい」ならまずはスキャフォールディングや Razor Pages 側の対応を検討するのが近道です。
移設・リマップ後のチェックリスト
| チェック項目 | 確認方法 | 引っかかりやすい症状 |
|---|---|---|
| 新 URL でログインできる | /Account/Login へ直接アクセス | 404、モデルバインドエラー |
| [Authorize] でログインへ飛ぶ先が正しい | 保護ページへ未ログインでアクセス | 旧 /Identity に飛ぶ、ループ |
| Logout が正しく動く | ログアウト後に認証状態を確認 | ログアウト後も認証が残る、404 |
| リンクが新 URL を生成する | ヘッダー/メニューのリンクをクリック | asp-area="Identity" が残り旧 URL へ |
| ReturnUrl で元ページへ戻る | 保護ページ→ログイン→戻り | ログイン後にトップへ飛ぶ、戻れない |
| AccessDenied の遷移が正しい | 権限不足を作ってアクセス | 403 のまま、404 |
まとめ
- 既定の Identity UI は Razor Pages の Identity エリアとして提供されるため、
/Identityを “設定だけで”/に置き換えることはできません。 MapIdentityApiは UI ではなく API エンドポイントを追加する仕組みなので、画面 URL の変更には効きません。- 短期のテストなら AddAreaPageRoute で追加ルートが最短。長期運用なら スキャフォールディングして @page などを編集して管理するのが確実です。
- どの方法でも、Cookie の LoginPath/LogoutPath/AccessDeniedPath を新 URL と一致させるのが必須です。

コメント