DI进入ASP.NET MVC 6中的需求/策略

Vi1*_*100 6 c# asp.net-identity asp.net-core-mvc asp.net-core

我正在寻找一种在ASP.NET 5中编写自定义授权过滤器的方法,因为当前的实现依赖于策略/需求,而这些策略/需求又仅仅依赖于声明的使用,因此在最初的不断变化的身份系统中我真的厌倦了(我已经尝试了所有的味道).

我有一大堆permisions(超过200),我不想编码声明,因为我拥有自己的存储库,并且比检查数百个字符串要快得多的检查方法(这就是声称是到底).

我需要在每个属性中传递一个参数,该参数应该根据我的自定义权限存储库进行检查:

[Authorize(Requires = enumPermission.DeleteCustomer)]
Run Code Online (Sandbox Code Playgroud)

我知道这不是最常见的情况,但我认为这不是一个优势.我试图按照@leastprivilege所描述的方式在他的宏观帖子"ASP.NET 5和MVC 6中的安全状态:授权"中实现它,但我和作者打了同样的墙,甚至打开了关于ASP.NET 5 github repo的一个问题,已经以一种不太明确的方式关闭了:链接

知道怎么做到这一点?也许使用其他类型的过滤器?在那种情况下,怎么样?

Kir*_*lla 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
}
Run Code Online (Sandbox Code Playgroud)