0

I have a use case where each logged in user has a set of URLs he/she can access regardless of his/her role. I am trying to implement a policy in ASP.Net-core 2.2 to achieve this. Each of the URLs accessible to the user would be registered as claim when the user is registered and while a request is made by the authenticated user, an attempt is made to compare the requested URL/path to the URL claims registered for the user.

Since I am trying to use authorization policy to achieve this, I have created the following Authorization Requirement and Handler

public class AccessPermissionRequirement : IAuthorizationRequirement
{
    public ControllerContext controllerContext { get; }
    public string routeArea = "";

    public AccessPermissionRequirement(ControllerContext _controllerContext, string RouteArea ="")
    {
        controllerContext = _controllerContext;
        routeArea = RouteArea;
    }

}

public class AccessPermissionHandler : AuthorizationHandler<AccessPermissionRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AccessPermissionRequirement requirement)
    {
        if (!context.User.Identity.IsAuthenticated)
        {
            return Task.CompletedTask;
        }
        var actionName = requirement.controllerContext.ActionDescriptor.ActionName;
        var controllerName = requirement.controllerContext.ActionDescriptor.ControllerName;

        var route = controllerName + "/" + actionName;
        if (context.User.HasClaim("Routes", route))
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }
}

Since the AccessPermissionRequirement class requires an injection of ControllerContext at the constructor for me to be able to have access to the current request (outside a controller), I am finding it difficult to register the policy in the ConfigureServices method of the Startup.cs class.

Below is what I have done that is not working

 services.AddAuthorization(options => {
            options.AddPolicy("CheckAccess", policy => policy.Requirements.Add(new AccessPermissionRequirement(ControllerContext controllerContext)));
        });

I am getting the following error

ControllerContext is a type which is not valid in the given context

So, I'm stuck here as I don't know the way to resolve this.

Sorry, it is my first time trying to implement policy in ASP.Net-core

I will appreciate a guide to resolve this.

Thank you

Josh
  • 1,258
  • 3
  • 21
  • 36
  • You can remove the ControllerContext from the requirement. The [requirement](https://docs.microsoft.com/aspnet/core/security/authorization/policies?#requirements) is in fact just a container to hold parameters. It's the RequirementHandler that has access to the context and handles the requirement. – Ruard van Elburg Sep 13 '19 at 21:21

1 Answers1

0

It seems that IAuthorizationFilter perfectly fits your case. There's a good discussion regarding this:

How do you create a custom AuthorizeAttribute in ASP.NET Core?

Ivan
  • 209
  • 2
  • 3
  • Yeah. That's the alternative I am currently trying to rather implement if I get no solution to using authorization policy. Thank you for confirming that – Josh Sep 01 '19 at 16:33