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

时间:2015-11-13 11:26:48

标签: c# asp.net-identity asp.net-core asp.net-core-mvc

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

我有一大堆permisions(超过200),我不想编写索赔,因为我拥有自己的存储库,并且检查它比检查数百个字符串(即什么声称到底是什么。)

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

[Authorize(Requires = enumPermission.DeleteCustomer)]

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

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

1 个答案:

答案 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
}