question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple values for single key in RouteClaimsRequirement

See original GitHub issue

New Feature

Allow claims to have an array value and not just a string value.

Motivation for New Feature

I have an application where I have multiple roles for my users. For endpoints that should only be reached by admins, I can use the following:

"RouteClaimsRequirement": {
	"Role": "Admin"
}

For endpoints that should only be reached by users, I can use the following:

"RouteClaimsRequirement": {
	"Role": "User"
}

For endpoints that should be reached by both users and admins I would like to use the following:

"RouteClaimsRequirement": {
	"Role": ["User", "Admin"]
}

When I tried adding this, all requests to the endpoint respond with a 404.

This should let the request go through if the request has a claim for the role user or admin. This is equivalent to the built-in asp .net core attribute: [Authorize(Roles = "User, Admin")]

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authorization.authorizeattribute.roles?view=aspnetcore-2.2

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:13
  • Comments:21 (3 by maintainers)

github_iconTop GitHub Comments

4reactions
arro000commented, Sep 27, 2021

I’ve tried the override authorisation middleware method , but the claims are strictly converted in a Dictionary<string,string> format before the middleware was called ;

This format break the Route because the value cannot be converted into a string;

"RouteClaimsRequirement": {
	"Role": ["User", "Admin"]
}

This format also don’t work because the Role key in dictionary will be ovverride with the second value;

"RouteClaimsRequirement": {
	"Role": "Admin"
        "Role": "User" 
}

so… My personal solution will be Workaround example

"RouteClaimsRequirement": {
	"Role": "Admin , User"
}

In the authorisation middleware method , i will parse the string with a regex pattern to obtain the single role value:

  public async void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            var configuration = new OcelotPipelineConfiguration
            {
                AuthorizationMiddleware = async (ctx, next) =>
                {
                    if (this.Authorize(ctx))
                    {
                        await next.Invoke();

                    }
                    else {
                       // ctx.Errors.Add(new UnauthorisedError($"Fail to authorize"));
                    }
                    
                }
            };
            .
            .
            .
            await app.UseOcelot(configuration);
      }

The logic of Authorize Method

 private bool Authorize(HttpContext ctx)
        {
           DownstreamRoute route = (DownstreamRoute)ctx.Items["DownstreamRoute"];
            string key = route.AuthenticationOptions.AuthenticationProviderKey;

            if (key == null || key == "") return true;
            if (route.RouteClaimsRequirement.Count == 0) return true;
            else
            {
            else {
                //flag for authorization
                bool auth = false;

                //where are stored the claims of the jwt token
                Claim[] claims = ctx.User.Claims.ToArray<Claim>();

                //where are stored the required claims for the route
                Dictionary<string, string> required = route.RouteClaimsRequirement;
                .
                .
                ((AUTHORIZATION LOGIC))
                .
                .
                return auth;
           }

remeber to add in the ConfigureService method

 services.AddAuthorization();
services.AddAuthentication()
                    .AddJwtBearer("TestKey", x =>
                    {
                      //  x.RequireHttpsMetadata = false;
                        x.TokenValidationParameters = tokenValidationParameters;
                    });

(I Still working on my Authorization logic that will implement the multiple claims with And/Or logic with regex of strings , but the claims data structure implemented with Dictionary<string , string> is very ugly and not very flexible)

//updated for last version of ocelot

1reaction
MuhammadSohaibSultancommented, Jul 1, 2020

by using @arro000 's trick I changed a few things to make it work for me on .Net Core 3.1 & Ocelot 16.0.1. My answer on Stackoverflow. https://stackoverflow.com/questions/60300349/how-to-check-claim-value-in-array-or-any-in-ocelot-gateway/62390542#62390542

Read more comments on GitHub >

github_iconTop Results From Across the Web

Multiple values for single key in RouteClaimsRequirement
Allow claims to have an array value and not just a string value.
Read more >
Handling the multiple values for single key in the API URL
I need to handle the multiple values for the single key in the URL. Ex: values/{values} => values/1,2,3. I refered the following URL:...
Read more >
[Solved]-Multiple values for single key-LINQ,C#
My colleague and I realized that we can keep track of the Category's and if same Category occurs, it means that only a...
Read more >
How to include multiple values on a key? And then iterate?
The lesson has conveyed that keys can have multiple values. 1) How would multiple values be created, for instance, in this exercise?
Read more >
Building your own ASP.Net Core API gateway with Ocelot
I am facing one issue with ocelot. Error logging is enabled in the gateway project.I can see only a message ocelot request key...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found