我是Identity API的新手,但在我的Web应用程序中:机构用户为自己的机构创建了其他用户,他们想确定是否看到此页面。我的控制器方法如下;
[Authorize]
public IActionResult Privacy()
{
return View();
}
但用户也有权执行任何操作,例如此枚举,并且枚举大于50;
public enum PermissionTypes
{
UserCreate = 1,
UserEdit = 2,
UserDelete = 3,
....
}
我进行了一些研究并发现了基于策略的授权,但是当您创建新策略时,必须在Startup.cs上声明,这对我不利,因为这样做时,您总是在生产中发布新代码。我需要的是这样的东西;
[CustomAuth(PermissionTypes.UserCreate)]
public IActionResult Privacy()
{
return View();
}
有什么解决方案吗?
有很多方法可以做到这一点。很多人推荐基于声明和基于策略的安全性...我个人发现此方法有些“僵硬”。
所以我做了一些不同的事情:
首先创建一个这样的类:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;
using Microsoft.AspNetCore.Identity;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace Bamboo.Web.CoreWebsite.Membership
{
public class PermissionHandler : AuthorizationHandler<RolesAuthorizationRequirement>
{
private readonly IUserStore<CustomUser> _userStore;
public PermissionHandler(IUserStore<CustomeUser> userStore)
{
_userStore = userStore;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RolesAuthorizationRequirement requirement)
{
if(context == null || context.User == null)
return;
var userId = context.User.FindFirst(c => string.CompareOrdinal(c.Type, ClaimTypes.NameIdentifier) == 0);//according to msdn this method returns null if not found
if(userId == null)
return;
// for simplicity, I use only one role at a time in the attribute
//but you can use multiple values
var permissions = requirement.AllowedRoles.ToList();
var hasPermissions = //here is your logic to check the database for the actual permissions for this user.
// hasPermissions is just a boolean which is the result of your logic....
if(hasPermissions)
context.Succeed(requirement);//the user met your custom criteria
else
context.Fail();//the user lacks permissions.
}
}
}
现在将PermissionHandler注入您的startup.cs文件中,如下所示:
public void ConfigureServices(IServiceCollection services)
{
// Custom Identity Services
........
// custom role checks, to check the roles in DB
services.AddScoped<IAuthorizationHandler, PermissionHandler>();
//the rest of your injection logic omitted for brevity.......
}
现在在您的操作中使用它:
[Authorize(Roles = PermissionTypes.UserCreate)]
public IActionResult Privacy()
{
return View();
}
注意,我没有创建自定义属性...就像我说的,有很多方法可以做到这一点。我更喜欢这种方式,因为它减少了代码,并且没有硬编码的策略或声明或任何其他复杂性,您可以使其成为100%由数据驱动的。
这是一个复杂的主题,因此可能需要对其进行一些额外的调整。
另外,我使用的ASP.NET Core 2.2可能不同于3.0。
但是它应该为您提供一种基于权限的授权方式。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句