これは複雑な質問であり、正しい答えはありませんが、それを行うにはいくつかの方法があります。最初に、要求ベースのjwtを使用してステートレス認証を使用していると仮定します。最も簡単な方法は、すべてのリクエストの前にユーザーロールを読み取る独自のポリシーを作成することです。
internal class DatabaseRoles : IAuthorizationRequirement
{
public string Role { get; }
public DatabaseRoles(string role)
{
Role = role;
}
}
internal class DatabaseRolesHandler : AuthorizationHandler<DatabaseRoles>
{
private readonly UserManager<IdentityUser> userManager;
public DatabaseRolesHandler(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager)
{
this.userManager = userManager;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, DatabaseRoles requirement)
{
//NOTE this is the out of the box implementation of roles and simple query to get the roles from the EF backed database. I would recoment makeing a custom privelages store for this and not using roles for this but access rights
var user = await userManager.FindByIdAsync(userManager.GetUserId(context.User));
if (await userManager.IsInRoleAsync(user, requirement.Role))
{
context.Succeed(requirement);
}
}
}
しかし、このソリューションは要求ごとにデータベースへの呼び出しを必要とするため、それほど高性能ではありません。これは負荷が小さい場合は問題ありませんが、トラフィックに問題が発生する可能性があります。もう1つの方法は、役割が変更されたときにすべてのユーザートークンを取り消すことですが、これは非常に複雑です。redisのようなロール用の高速アクセスストアを作成すると、すべての呼び出しでチェックを行う問題は発生しません。また、独自のユーザーストレージを作成することはお勧めしません。セキュリティ基準に関して最新の状態を維持し、維持することは悪夢だからです。
Authorize(Roles ="Staff")
ロールを持つユーザーStaff
のみがこのアクションにアクセスできることを確認します...したがって、ユーザーがこのロールから削除されると、ユーザーはこれにアクセスできなくなります。これは発生していませんか?