web-dev-qa-db-ja.com

ASP.NET Coreでランタイム認証を設定するにはどうすればよいですか?

私はロールベースのモジュール管理があり、いつでもいつでも変更されるという点でアプリケーションを作成しています。シナリオ:

  • ユーザーが従業員の作成と表示にアクセスできる場合、ユーザーは従業員の作成と表示しかできませんが、将来の管理者はユーザーの役割を作成と表示から表示と削除に変更するだけで、ユーザーはそのアクティビティしか実行できません。

私は[Authorize(Roles ="Staff")]で試しますが、管理者がランタイムを変更した場合、管理されません。

誰かがこれを調べて私に連絡してもらえますか?

8
Deep Soni

これは複雑な質問であり、正しい答えはありませんが、それを行うにはいくつかの方法があります。まず、クレームベースのjwtを使用してステートレス認証を使用していると仮定します。最も簡単な方法は、独自の Policy を記述することです。これは、すべてのリクエストの前にユーザーロールを読み取ります。これは、これを行う最も簡単な方法であり、実装が最も高速です。 。

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のようなロール用の高速アクセスストアを作成すると、すべての呼び出しでチェックを実行する問題は発生しません。また、独自のユーザーストレージを作成することはお勧めしません。セキュリティ標準に関して最新の状態を維持し、維持することは悪夢だからです。

1
Filip Cordas