私はRBACとOIDC両方使っています。そしてDuende IdentityServerをOIDC Providerとして、.NETのMVCプロジェクトはそれを通して認証します。
RBACといえば、Roleの値が必要でしょうね。でもRoleというキーはOIDCのScopeの世界にないです。だから自分でカスタマイズのScopeとして実装しないといけないです。
まず一番やることは、自分のUserClaimsPrincipalFactoryを作ることです。
public class ApplicationUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
{
var identity = await base.GenerateClaimsAsync(user);
var roles = await _userManager.GetRolesAsync(user);
identity.AddClaims(roles.Select(role => new Claim(JwtClaimTypes.Role, role)));
// 他のClaimもいるなら、ここに追加して
// ...
return identity;
}
}
このあとは、作ったClaimsPrincipalFactoryを利用するように登録します。
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
.AddClaimsPrincipalFactory<ApplicationUserClaimsPrincipalFactory>()
これで、IdentityServer側、ソースに関する変更は全て完了です。このあと、Identity Resourcesに role というリソースを追加して、さらに role という UserRoleをAPI ResourceとClientのAllowed Scopeに追加してください。これはTokenにRoleのキーを入れる指示とRoleのClaimを受け取る許可の意味が含まれています。追加する方法は、ソースに起動するとき初期化するロジックを書くか、管理者ツールで設定するかどっちでもいいです。私は管理者システムを作ったから、Webでこれらの資源を更新します。
ここまできたら、もうIdentityServerからRoleのClaim送ってくれます。しかし、.NETはちゃんと理解してCookieに書いてくれるか。答えはネガティヴ。
openIdConnectOptions.Scope.Add("role");
openIdConnectOptions.ClaimActions.MapJsonKey("role", "role", "role");
openIdConnectOptions.TokenValidationParameters.RoleClaimType = "role";
以上の3行はAddOpenIdConnect()の時に追加してください。1行目は、roleのClaimが欲しい意味で、IdentityServer側のAllowed Scopeと関連しています。2行目は、認証が必要なサーバーが受け取った Role ClaimをCookieに入れる指示です。3行目は、受け取ったRoleキーをそのまま受け取って、名前書き換えないでと.NETに命令する意味です。
これでRBACは使えるようになるはずです。