我正在寻找一种在ASP.NET 5中编写自定义授权过滤器的方法,因为当前的实现依赖于策略/要求,而这些策略/要求又仅仅依赖于声明的使用,因此是在无数个变化的身份上我真的厌倦了系统(我已经尝试了所有的味道)。
我有一大堆permisions(超过200),我不想编写索赔,因为我拥有自己的存储库,并且检查它比检查数百个字符串(即什么声称到底是什么。)
我需要在每个属性中传递一个参数,该参数应根据我的自定义权限存储库进行检查:
[Authorize(Requires = enumPermission.DeleteCustomer)]
我知道这不是最常见的情况,但我认为这不是一个优势。我试图按照@leastprivilege所描述的方式在他的宏观帖子“ASP.NET 5和MVC 6中的安全状态:授权”中实现它,但我和作者打了同样的墙,甚至打开了ASP.NET 5 github repo上的一个问题,已经以一种不太明确的方式关闭了:link
知道怎么做到这一点?也许使用其他类型的过滤器?在那种情况下,怎么样?
答案 0 :(得分:1)
以下是如何实现此方案的示例:
假设您有一个名为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
}