猿问

来自数据库表的 ASP.NET Core 2 授权

我有一系列网页,这些网页的授权是在自定义数据库表中定义的。例如,我有一个名为“超级用户”的角色,该角色允许访问某些网页。我有分配给该角色的用户。

我不明白如何将 Authorize 属性放在控制器上并传入页面名称(视图),然后从我的数据库中读取某种类型的自定义处理程序以查看用户是否在具有权限的组中. 我一直在这里阅读基于策略的授权:https ://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2并试图理解它我的情况。

我是否在基于策略的授权的正确轨道上,或者在允许用户访问页面之前是否有另一种方法来进行数据库检查权限?


慕慕森
浏览 122回答 2
2回答

慕码人8056858

该Authorize属性本身仅用于指定您在特定页面或控制器上所需的授权类型。此属性旨在与身份框架一起使用,并且可以包括角色、策略和身份验证方案。您需要在 Identity 框架和您的数据库之间建立一座桥梁,这可以通过自定义UserStoreand来完成RoleStore,这在此页面上有详细描述。总结一个相当复杂的过程:该Authorize属性指示浏览器对您的用户进行身份验证您的用户被重定向到身份验证页面如果成功,您将获得一个ClaimsPrincipal实例,然后您需要通过自定义映射到您的数据库用户UserStore然后可以根据数据库角色检查您的用户这是所有这些实际操作的简短示例(不完全完整,因为它的代码太多了)。启动.cs// This class is what allows you to use [Authorize(Roles="Role")] and check the roles with the custom logic implemented in the user store (by default, roles are checked against the ClaimsPrincipal roles claims)public class CustomRoleChecker : AuthorizationHandler<RolesAuthorizationRequirement>{&nbsp; &nbsp; private readonly UserManager<User> _userManager;&nbsp; &nbsp; public CustomRoleChecker(UserManager<User> userManager)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _userManager = userManager;&nbsp; &nbsp; }&nbsp; &nbsp; protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var user = await _userManager.GetUserAsync(context.User);&nbsp; &nbsp; &nbsp; &nbsp; // for simplicity, I use only one role at a time in the attribute&nbsp; &nbsp; &nbsp; &nbsp; var singleRole = requirement.AllowedRoles.Single();&nbsp; &nbsp; &nbsp; &nbsp; if (await _userManager.IsInRoleAsync(user, singleRole))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.Succeed(requirement);&nbsp; &nbsp; }}public void ConfigureServices(IServiceCollection services){&nbsp; &nbsp; services&nbsp; &nbsp; .AddIdentity<User, Role>()&nbsp; &nbsp; .AddUserStore<MyUserStore>()&nbsp; &nbsp; .AddRoleStore<MyRoleStore>();&nbsp; &nbsp; // custom role checks, to check the roles in DB&nbsp;&nbsp; &nbsp;services.AddScoped<IAuthorizationHandler, CustomRoleChecker>();}您的 EF Core 实体在哪里User,是哪里。Role我的用户商店public class MyUserStore : IUserStore<User>, IUserRoleStore<User>, IQueryableUserStore<User>{&nbsp; &nbsp; private Context _db;&nbsp; &nbsp; private RoleManager<Role> _roleManager;&nbsp; &nbsp;...&nbsp; &nbsp; public async Task<User> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // bridge your ClaimsPrincipal to your DB users&nbsp; &nbsp; &nbsp; &nbsp; var user = db.Users.SingleOrDefault(_ => _.Email.ToUpper() == normalizedUserName);&nbsp; &nbsp; &nbsp; &nbsp; return await Task.FromResult(user);&nbsp; &nbsp; }&nbsp; &nbsp;...&nbsp; &nbsp; public async Task<bool> IsInRoleAsync(User user, string roleName, CancellationToken cancellationToken)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (roleName == null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; // your custom logic to check role in DB&nbsp; &nbsp; &nbsp; &nbsp; var result = user.Roles.Any(_ => _.RoleName == roleName);&nbsp; &nbsp; &nbsp; &nbsp; return await Task.FromResult(result);&nbsp; &nbsp; }

呼唤远方

.Net Core -> 如果要使用基于策略的方法,则必须在 startup.cs 的 ConfigureServices 方法中定义策略定义例子:&nbsp;services.AddAuthorization(options =>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options.AddPolicy("UserPolicy", policy => policy.RequireRole("USER"));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });然后您可以在控制器或操作方法中应用如下策略。授权(策略 = “用户策略”)
随时随地看视频慕课网APP
我要回答