0
votes

I have a question about Claims, JWT, and ASP.Net Core. Again... (Greetings Chris). So...

I have my JWT with Claim:

"Authorization": "CanEditUnit,CanBrowseUnit,CanCreateUnit,CanDeleteUnit,CanSeeUnitDetails,CanBrowseRole,CanEditRole,CanCreateRole,CanDeleteRole,CanSeeRoleDetails,CanBrowseUser,CanSeeUserDetails,CanDeleteUser,CanEditUser,CanRegisterNewUser"

etc.

This Claim has all privileges, that user contains (for example: If the user has CanEditUnit in a database set to True, CanEditUnit is saved in Authorization Claim, but if something is set to False it simply doesn't appear in that Claim.

Then I want to check if user has that Privilages in Policies like that:

options.AddPolicy("CanEditUnit", policy => policy.RequireClaim("Authorization", "CanEditUnit"));

But it probably checks if Authorization Claim is equal to CanEditUnit.

Is there a way to check policies with Contains instead of Equal? If not, what should I do them?

I found this in docs, but I don't know how to use it.

1

1 Answers

2
votes

As you've suggested in your question, it looks like RequireAssertion has the ability to handle this for you. Here's an example:

policy.RequireAssertion(ctx =>
{
    var authorizationClaim = ctx.User.FindFirstValue("Authorization");

    if (authorizationClaim == null)
        return false;

    return authorizationClaim.Split(",").Contains("CanEditUnit");
});

This simply looks for an Authorization claim and, if it exists, splits it by , and checks for the existence of a CanEditUnit value.

If you want something a little more reusable, you can create a custom AssertionRequirement class of your own. Here's an example of what that might look like:

public class CustomAssertionRequirement : AssertionRequirement
{
    public CustomAssertionRequirement(string requiredValue)
        : base(ctx => HandleRequirement(ctx, requiredValue)) { }

    private static bool HandleRequirement(AuthorizationHandlerContext ctx, string requiredValue)
    {
        var authorizationClaim = ctx.User.FindFirstValue("Authorization");

        if (authorizationClaim == null)
            return false;

        return authorizationClaim.Split(",").Contains(requiredValue);
    }
}

In order to use this new class, you can add it as a requirement to the AuthorizationPolicyBuilder (instead of using RequireAssertion), like so:

policy.AddRequirements(new CustomAssertionRequirement("CanEditUnit"));