我正在寻找一种在 ASP.NET 5 中编写自定义授权过滤器的方法,因为当前的实现依赖于策略/要求,而后者又完全依赖于声明的使用,因此依赖于无数个不断变化的身份我真的厌倦了它的系统(我已经尝试过它的所有口味)。
我有一大组权限(超过 200 个),我不想将其编码为 Claims,因为我有自己的存储库,并且比比较数百个字符串(即到底是什么主张)。
我需要在每个属性中传递一个参数,该参数应该根据我的自定义权限存储库进行检查:
[Authorize(Requires = enumPermission.DeleteCustomer)]
我知道这不是最常见的情况,但我认为这不是边缘情况。我已经尝试按照@leastprivilege 在他的宏伟帖子“ASP.NET 5 和 MVC 6 中的安全状态:授权”中描述的方式实现它,但我遇到了与作者相同的问题,他甚至打开了ASP.NET 5 github repo 上的一个问题,已以不太明确的方式关闭:link
知道如何实现吗?也许使用其他类型的过滤器?那怎么办呢?
最佳答案
以下是如何实现此场景的示例:
假设您有一个名为 IPermissionStore
的服务,它会验证给定用户是否具有在属性上指定的所需权限。
public class MyCustomAuthorizationFilterAttribute : Attribute, IFilterFactory, IOrderedFilter
{
private readonly Permision[] _permissions;
public MyCustomAuthorizationFilterAttribute(params Permision[] permissions)
{
_permissions = permissions;
}
public int Order { get; set; }
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
var store = serviceProvider.GetRequiredService<IPermissionStore>();
return new MyCustomAuthorizationFilter(store, _permissions)
{
Order = Order
};
}
}
public class MyCustomAuthorizationFilter : IAuthorizationFilter, IOrderedFilter
{
private readonly IPermissionStore _store;
private readonly Permision[] _permissions;
public int Order { get; set; }
public MyCustomAuthorizationFilter(IPermissionStore store, params Permision[] permissions)
{
_store = store;
_permissions = permissions;
}
public void OnAuthorization(AuthorizationContext context)
{
// Check if the action has an AllowAnonymous filter
if (!HasAllowAnonymous(context))
{
var user = context.HttpContext.User;
var userIsAnonymous =
user == null ||
user.Identity == null ||
!user.Identity.IsAuthenticated;
if (userIsAnonymous)
{
Fail(context);
}
else
{
// check the store for permissions for the current user
}
}
}
private bool HasAllowAnonymous(AuthorizationContext context)
{
return context.Filters.Any(item => item is Microsoft.AspNet.Authorization.IAllowAnonymous);
}
private void Fail(AuthorizationContext context)
{
context.Result = new HttpUnauthorizedResult();
}
}
// Your action
[HttpGet]
[MyCustomAuthorizationFilter(Permision.CreateCustomer)]
public IEnumerable<string> Get()
{
//blah
}
关于c# - DI 到 ASP.NET MVC 6 中的需求/策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33691696/