DI in Requirement / Policy in ASP.NET MVC 6

I am looking for a way to program a custom authorization filter in ASP.NET 5, because the current implementation depends on the Policy / Requirement, which, in turn, rely solely on the use of Claims, thus on an unmanaged and constantly changing Identity System, which I'm very tired of ( I tried it all deliciously).

I have a large set of permissions (over 200) that I don’t want to code as claims, because I have my own repository for them and a much faster way to check it than to compare hundreds of lines (these are the claims at the end).

I need to pass a parameter in every attribute that needs to be checked against my custom permissions repository:

[Authorize(Requires = enumPermission.DeleteCustomer)] 

I know that this is not the most common scenario, but I think this is not an extreme case. I tried to implement it as @leastprivilege described in his excellent post "Security Status in ASP.NET 5 and MVC 6: Authorization", but I ended up on the same walls as the author who even discovered the problem in the ASP.NET repository 5 github that was not closed too clearly: link

Any idea on how to achieve this? Maybe use a different kind of filter? In this case, how?

+6
source share
1 answer

The following is an example of how you can achieve this scenario:

Suppose you have a service called IPermissionStore that checks to see if a given user has the required permissions specified in the attribute.

 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 } 
+1
source

All Articles