Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create attribute to check if the user has a claim with Identity core 2.2?

I have an application written with C# on the top on ASP.NET Core 2.2 framework.

I want to be able to check if a user has a claim before I allow them access to the action.

I created an AuthorizationHandler to check if the user has the claim like so

public class ClaimExistanceHandler : AuthorizationHandler<MustHaveClaimRequirement>
    {
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, MustHaveClaimRequirement requirement)
        {
            if (context == null
                || context.User == null
                || context.User.Identity == null
                || !context.User.Identity.IsAuthenticated
                || requirement == null
                || string.IsNullOrWhiteSpace(requirement.Type)
                || context.User.HasClaim(requirement.Type, requirement.Value))
            {
                context.Fail();

            }
            else
            {
                context.Succeed(requirement);
            }

            await Task.Yield();
        }
    }
}

then the requirement is as follow

public class MustHaveClaimRequirement : IAuthorizationRequirement
{
    public string Type { get; set; }
    public string Value { get; set; }

    public MustHaveClaimRequirement(string type, string value)
    {
        Type = type;
        Value = value;
    }
}

But how can I call this requirement as an attribute? For example HasPermission("do something", "1")

It seems that my HasPermission class needs to implement the AuthorizeAttribute but not sure how would I call the handler from the attribute.

like image 659
Junior Avatar asked Sep 14 '25 23:09

Junior


1 Answers

Your primary goal here is to get the requirement into a policy, and then use or create an attribute that can specify that policy with a string name. Once you do that, don't need to worry about calling the handler yourself, because ASP.NET Core will take care of that for you.

The simplest method of creating policies is to do it on app startup, as documented here. You create your policies, then use AuthorizeAttribute to specify which policy to attach to each endpoint.

However, doing it this way requires you to define all your policies up front. If that would result in you needing to create tons of different policies (because you are going to be checking lots of different claim types), and what you really want is to be able to have an attribute that specifies the claim information, there is a more dynamic way of doing it: see here. You need to create an AuthorizeAttribute implementation that stuffs your parameter values (name and type) into a string, and create and register an IAuthorizationPolicyProvider that can interpret that string and generate a policy with the appropriate requirement.

EDIT: It's also worth pointing out that ASP.NET Core already includes a requirement implementation for checking a claim: ClaimsAuthorizationRequirement. AuthorizationPolicyBuilder has a shortcut for it (RequireClaim) so you can quickly create policies that check claims:

services.AddAuthorization(options =>
    {
        options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("EmployeeNumber"));
    });
like image 62
nlawalker Avatar answered Sep 16 '25 12:09

nlawalker