以前、ASP.NET Core Identity は Claim ベースの認証を使用していると述べましたが、実際には ASP.NET Core Identity には異なる種類の承認方法があります。最も簡単な ログイン承認、ロール承認、Claim 承認 ですが、これらはすべて一つの方法で実現されています。それは原則承認(Policy-based authorization)です。
いわゆる原則承認とは、カスタムポリシー を定義し、そのポリシーが定義する条件を満たせば承認を得られるというものです。その条件がログインユーザーが誰であるか、特定のロール を持つこと、特定のClaim を持つこと、あるいは ロールとClaimの両方 を持つことなど、いずれでも構いません。
最初は理解しにくいかもしれませんが、筆者も時間をかけて理解しました。Claim は new Claim("Age", "18") のような情報のセットに対応し、ポリシーは例えば「あるバーではユーザーの年齢が18歳以上でなければ入店できない」というルールに相当します。以前、Role は型が Role の Claim であると述べましたので、同じ考え方です。
ASP.NET Core でポリシーを定義するのも難しくありません。Program.cs で定義するだけです。以下のコードでは "IsAdmin" という名前のポリシーを定義し、このポリシーは承認を得るために "ManageRole" という Claim が必要であると指定しています。
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("IsAdmin", policy => { policy.RequireClaim("ManageRole"); });
});
以前作成したユーザーのClaim編集ページに適用する場合、現在ログインしている test@gmail.com にすべてのClaimを保持させます。そうしないと、適用後にこれらのページが見えなくなります。また、user@gmail.com も編集しますが、Claimを何も選択せずにそのまま保存し、後でテストできるようにします。

アプリケーションへの適用もRoleと同じで、[AuthorizeAttribute] の後に Policy パラメータを指定するだけです。UserManagement.razor を例に挙げます。
@page "/UserManagement/UserList" @attribute [Authorize(Policy = "IsAdmin")] …
NavMenu.razor にも新しい <AuthorizeView> コンポーネントを追加し、変数に Policy を適用します。
<AuthorizeView Policy="IsAdmin">
<Authorized>
<li class="nav-item px-3">
<NavLink
class="nav-link"
href="UserManagement/UserList"
Match="NavLinkMatch.All"
>
<span class="bi bi-people h4 p-2 mb-0" aria-hidden="true"></span> Users
</NavLink>
</li>
</Authorized>
</AuthorizeView>
しかし、この時点で user@gmail.com でログインしても User 管理ページ が見えてしまいます。ManageUser の値は false なのに、なぜでしょうか? これは Policy "IsAdmin" が "ManageRole" という ClaimType だけを要求しているためです。通常、システムはこのように承認せず、ClaimType と ClaimValue の両方を比較します。そこで、Policy "IsAdmin" を改良し、"IsAdmin" の ClaimValue が "true" でなければならないと指定することで、簡易的な Policy 承認 が完成します。


また、注意点として ASP.NET Core は ClaimType の処理では 大文字小文字を区別しません が、ClaimValue では 大文字小文字を区別します。Policy "IsAdmin" を例にとると、ClaimType は "manageUser" でも "manageuser" でも構いませんが、ClaimValue は "true" でなければなりません。
引用:
- Policy-based Authorization in ASP.NET Core – A Deep Dive
- Claim type and claim value in claims policy based authorization in asp net core
- Simple authorization in ASP.NET Core
注:本稿のコードは .NET 6 + Visual Studio 2022 でリファクタリングされています。原文リンクからリファクタリング後のコードと比較して学習できます。ご一読いただき、原作者をサポートしていただけると幸いです。