Skip to content

RouteClaimsRequirement Not Enforced Even When Token Is Authenticated and Contains Required Claim - ocelot 24.0.0 #2290

@Naihan

Description

@Naihan

When using RouteClaimsRequirement in Ocelot with Azure AD and a validated JWT token, Ocelot logs "No authorization needed for upstream path" and does not enforce the claim check, even though:

  • The route has valid AuthenticationOptions and RouteClaimsRequirement
  • The token is successfully authenticated.
  • The token includes the required claim.

Expected behavior, Ocelot should:

  • Match the route
  • Authenticate the token using the registered scheme
  • Evaluate the RouteClaimsRequirement
  • Return 403 Forbidden if claim is missing or invalid
  • Instead, Ocelot skips claim checking entirely.

c# code

builder.Configuration.AddJsonFile("ocelot.json");

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration, configSectionName: "AzureAd");

builder.Services.AddOcelotAzureAdAuthatication(builder.Configuration, configSectionName: "AzureAd"); //custom service that authanticate using azure ad

builder.Services.AddOcelot();

builder.Services.AddAuthorization();

var app = builder.Build();

app.UseMiddleware<AzureAdAuthaticationMiddlware>(); //custom middlware that authanticate using azure ad
app.UseAuthentication();
app.UseAuthorization();

await app.UseOcelot();

app.Run();

ocelot.json

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/data",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "api.example.com",
          "Port": 443
        }
      ],
      "UpstreamPathTemplate": "/data",
      "UpstreamHost": "grafana.example.com",
      "UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE" ],
      "AuthenticationOptions": {
        "AuthenticationProviderKey": "Bearer"
      },
      "RouteClaimsRequirement": {
        "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": [ "non-exiting-role" ]
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "https://localhost:5000"
  }

the jwt contains a claim :

"claim": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" = "Admin"

logs show:

Client has been authenticated for path '/data'
No authorization needed for upstream path: /data

full log:

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://[::]:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\Users\NimrodDavidKenDror\source\repos\Nanox.Cloud.ApiGateway\src\Nanox.Cloud.ApiGateway
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://grafana.example.com:5000/data - - -
info: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
      Microsoft.IdentityModel Version: 7.6.2.0. Date 05/01/2025 21:08:10. PII logging is OFF. See https://aka.ms/IdentityModel/PII for details.
      IDX10242: Security token: '[PII of type 'Microsoft.IdentityModel.JsonWebTokens.JsonWebToken' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]' has a valid signature.
info: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
      IDX10239: Lifetime of the token is valid.
info: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
      IDX10234: Audience Validated.Audience: '4994c85b-df6f-4923-9c63-b41c02f21cd9'
info: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
      IDX10245: Creating claims identity from the validated token: '[PII of type 'Microsoft.IdentityModel.JsonWebTokens.JsonWebToken' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
info: Ocelot.RateLimiting.Middleware.RateLimitingMiddleware[0]
      RequestId: 0HNC8UH3CEF3K:00000001, PreviousRequestId: -
      EnableEndpointEndpointRateLimiting is not enabled for downstream path: /data
info: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0]
      RequestId: 0HNC8UH3CEF3K:00000001, PreviousRequestId: -
      The path '/data' is an authenticated route! AuthenticationMiddleware checking if client is authenticated...
info: Ocelot.Authentication.Middleware.AuthenticationMiddleware[0]
      RequestId: 0HNC8UH3CEF3K:00000001, PreviousRequestId: -
      Client has been authenticated for path '/data' by 'AuthenticationTypes.Federation' scheme.
info: Ocelot.Authorization.Middleware.AuthorizationMiddleware[0]
      RequestId: 0HNC8UH3CEF3K:00000001, PreviousRequestId: -
      route is authenticated scopes must be checked
info: Ocelot.Authorization.Middleware.AuthorizationMiddleware[0]
      RequestId: 0HNC8UH3CEF3K:00000001, PreviousRequestId: -
      user scopes is authorized calling next authorization checks
info: Ocelot.Authorization.Middleware.AuthorizationMiddleware[0]
      RequestId: 0HNC8UH3CEF3K:00000001, PreviousRequestId: -
      No authorization needed for upstream path: /data
info: Ocelot.Requester.Middleware.HttpRequesterMiddleware[0]
      RequestId: 0HNC8UH3CEF3K:00000001, PreviousRequestId: -
      200 OK status code of request URI: https://api.example.com/data
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/2 GET https://grafana.example.com:5000/data - 200 - application/json;+charset=utf-8 1713.5335ms
info: Microsoft.AspNetCore.Hosting.Diagnostics[16]
      Request reached the end of the middleware pipeline without being handled by application code. Request path: GET https://grafana.example.com:5000/data, Response status code: 200

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions