Skip to content

AllowedScopes feature is not functioning as anticipated during authentication with the OpenIddict server #2177

Open
@hosamyousof

Description

@hosamyousof

Expected Behavior

The quote from the documentation: Authentication | Allowed Scopes

If you add scopes to AllowedScopes, Ocelot will get all the user claims (from the token) of the type scope and make sure that the user has at least one of the scopes in the list.

Actual Behavior

Validating one scope is not working and return 403 Forbidden.
The user access token has permission to two scopes 'InfraAPIs AdminAPIs' and I want to validate the InfraAPIs scope only in the rule in ocelot.json like:

{
  "DownstreamPathTemplate": "/log/{url}",
  "DownstreamScheme": "https",
  "DownstreamHostAndPorts": [
    {
      "Host": "localhost", "Port": 5004
    }
  ],
  "UpstreamPathTemplate": "/log/{url}",
  "UpstreamHttpMethod": [ "Get", "Post" ],
  "AuthenticationOptions": {
    "AuthenticationProviderKey": "OpenIddict.Validation.AspNetCore",
    "AllowedScopes": ["InfraAPIs"]
  }

Error log message from ocelot:

warn: Ocelot.Responder.Middleware.ResponderMiddleware[0]
      requestId: 0HN7E54RBBKV6:00000003, previousRequestId: No PreviousRequestId, message: 'Error Code: ScopeNotAuthorizedError Message: no one user scope: 'InfraAPIs AdminAPIs' match with some allowed scope: 'InfraAPIs' errors found in ResponderMiddleware. Setting error response for request path:/log/App/UpdateAPIAppLastConnectionDate, request method: POST'

OpenIddict validation handler configuration in program.cs:

// Add services to the container.
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
});

// Register the OpenIddict validation components.
builder.Services.AddOpenIddict()
    .AddValidation(options =>
    {
        // Note: the validation handler uses OpenID Connect discovery
        // to retrieve the address of the introspection endpoint.
        options.SetIssuer("https://localhost:5001/");
        //options.AddAudiences("rs_SubscriptionAPI");

        //either user clientid and client secret or AddEncryptionKey to be used for validation

        // Configure the validation handler to use introspection and register the client
        // credentials used when communicating with the remote introspection endpoint.
        //options.UseIntrospection()
        //        .SetClientId("rs_SubscriptionAPI")
        //        .SetClientSecret("SubscriptionAPISecret");

        // Register the encryption credentials. This sample uses a symmetric
        // encryption key that is shared between the server and the Api2 sample
        // (that performs local token validation instead of using introspection).
        //
        // Note: in a real world application, this encryption key should be
        // stored in a safe place (e.g in Azure KeyVault, stored as a secret).
        options.AddEncryptionKey(new SymmetricSecurityKey(
            Convert.FromBase64String("<EncryptionKey>")));

        // Register the System.Net.Http integration.
        options.UseSystemNetHttp();

        // Register the ASP.NET Core host.
        options.UseAspNetCore();
    });

If I set all the scopes it's working but I want only to set one scope for the rule in ocelot.json.

Steps to Reproduce the Problem

Use the provided configuration and make call to endpoint.

Specifications

  • Version: 23.3.4
  • Platform: .NET 8
  • Subsystem: windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    AuthenticationOcelot feature: AuthenticationAuthorizationOcelot feature: AuthorizationSpring'25Spring 2025 releaseacceptedBug or feature would be accepted as a PR or is being worked onhighHigh priorityproposalProposal for a new functionality in Ocelot

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions