3

I have to migrate an app with custom authorizaton based on the presence of "keys" and "doors". Basically a number of keys are assigned to a user and that user can('t) do things / open doors based on the keys he got.

The obvious solution is moving to Claims-based authorization of ASP.Net Core Identity. Each key become a claim. The point is that I would like to check directly for the presence of the claim to open the door and not for the Policy. This to avoid to write (lots of as there are hundreds of keys) code.

So, from:

Startup.cs:
   options.AddPolicy("Key1", policy => policy.RequireClaim("Key1"));
Controller:
   [Authorize(Policy = "Key1")]

To something like:

Controller:
   [Authorize(Claim = "Key1")]

Which is the best way to achieve this?

Pietro
  • 751
  • 7
  • 22

1 Answers1

5

The recommend way is to use Policy based authorization , you can click here for similar discussion .

You can use custom authorization filter to meet your requirement , if you just check whether claim type exists in user's claims , you can try below code sample :

ClaimRequirementFilter.cs :

public class ClaimRequirementFilter : IAuthorizationFilter
{
    readonly Claim _claim;

    public ClaimRequirementFilter(Claim claim)
    {
        _claim = claim;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == _claim.Type);
        if (!hasClaim)
        {
            context.Result = new ForbidResult();
        }
    }
}

ClaimRequirementAttribute.cs :

public class ClaimRequirementAttribute : TypeFilterAttribute
{
    public ClaimRequirementAttribute(string claimType ) : base(typeof(ClaimRequirementFilter))
    {
        Arguments = new object[] { new Claim(claimType , "") };
    }
}

And use like :

[ClaimRequirement("key")]

If you also need to restrict value of claim , you can follow the code sample from above link .

Nan Yu
  • 26,101
  • 9
  • 68
  • 148