我试图在ASP.NET vNext中创建一个自定义授权属性,直到我在这篇文章中找到@blowdart的这个优秀答案:
https://stackoverflow.com/a/31465227/1756978
表示授权要求现在是可行的方法。答案非常明确,但没有说明如何将参数传递给此要求/政策。
我要做的是移植具有此签名的MVC 5自定义授权属性:
[Autorizacion(Requires = enumPermission.DeleteCustomer)]
因为我使用在后端/前端镜像的一组非常自定义的权限作为枚举/字符串。
由于这些功能仍然没有记录,我觉得有点迷失......有人可以提供指导吗?
提前致谢
答案 0 :(得分:0)
确实,@ blowdart的帖子非常有见地,根据我的理解,要理解的关键是以下内容:
对身份的授权法。身份由...创建 认证
所以看来身份是由身份验证过程创建的。
然后(如果您愿意)您可以启动授权流程。这意味着创建一个自定义authorization requirements
,此要求将查看这些身份并对其采取行动。
用简单的英语说,这就是我认为正在发生的事情:
正如在blowdart的帖子中提到的,我们应该有某种形式
认证中间件碰巧做了实际的
认证。一旦成功通过身份验证,您就可以采取任
您想从现在经过身份验证的用户那里获得的信息并创建一个
经过身份验证的ClaimsPrincipal
。
例如,我们可以存储ClaimsPrincipal
个集合
用户拥有的权限。
然后,当您创建authorization requirement
时,您会看到
ClaimsPrincipal
,从中提取权限集
ClaimsPrincipal
并根据任何事情采取适当的行动
你想要的商业规则。
假设您无法将权限集存储到
ClaimsPrincipal
由于某种原因,可以轻松存储UserId
从需求中,从中读取UserId
ClaimsPrincipal
,调用数据库并获取权限集
然后对他们采取行动。
结论:
所以简而言之,我认为你传递东西并不符合要求,我认为你从ClaimsPrincipal
中获得。
在您的示例中,您可以创建一个读取ClaimsPrincipal
的要求,并将与Enum
的任何值进行比较并对其采取行动。
告诉我们您的设施以及是否有效。
如果我对此的理解是错误的,那么无论如何,请随意纠正我,因为所有这些都是新的东西: - )
答案 1 :(得分:0)
我碰巧提出了一种可以满足我的要求的工作环境,希望它也能对您有所帮助。
就我而言,我需要将IHttpContextAccessor
和EFCore的AppDbContext
传递给我的Requirement类。
在我的Startup.cs
中,我这样写:
services.AddAuthorization(options =>
{
options.AddPolicy("ThePolicy", policy => policy.Requirements.Add( new ThePolicyRequirement() ));
});
services.AddScoped<IAuthorizationHandler, ThePolicyAuthorizationHandler>();
ThePolicyAuthorizationHandler
类:
public class ThePolicyAuthorizationHandler : AuthorizationHandler<ThePolicyRequirement>
{
readonly AppDbContext _appContext;
readonly IHttpContextAccessor _contextAccessor;
public ThePolicyAuthorizationHandler(AppDbContext c, IHttpContextAccessor ca)
{
_appContext = c;
_contextAccessor = ca;
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, ThePolicyRequirement requirement)
{
var result = await requirement.isPass(_appContext, _contextAccessor, context);
if (result)
context.Succeed(requirement);
else
context.Fail(requirement);
}
}
和ThePolicyRequirement
类:
public class ThePolicyRequirement : IAuthorizationRequirement
{
AppDbContext _context;
IHttpContextAccessor _contextAccessor;
AuthorizationHandlerContext _authHandlerContext;
public async Task<bool> isPass(AppDbContext context, IHttpContextAccessor contextAccessor, AuthorizationHandlerContext authorizationHandlerContext)
{
_context = context;
_contextAccessor = contextAccessor;
_authHandlerContext = authorizationHandlerContext;
//logic here
return result;
}
}
关键思想是使用ThePolicyAuthorizationHandler
获得尽可能多的所有所需对象,并将其传递给ThePolicyRequirement
以执行授权机制的逻辑。