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.

Duende.IdentityServer from Blazor WebAssembly App protecting ASP.NET Core API using Client Credentials with custom allowed scope - invalid_scope

See original GitHub issue

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

I have a Blazor WebAssembly App created with Microsoft Visual Studio with these specifications: Target Framework .NET 6.0, Authentication Type Individual Accounts and ASP.NET Core Hosted:

Using this answer I have been able to add Client Credentials flow

https://stackoverflow.com/a/67324222/3850405

I removed this from appsettings.json:

"Clients": {
  "WebApplication4.Client": {
    "Profile": "IdentityServerSPA"
  }
}

Edit Startup.cs or Program.cs:

services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
    {
        options.Clients.AddIdentityServerSPA("WebApplication4.Client", builder =>
        {
            builder.WithRedirectUri("/authentication/login-callback");
            builder.WithLogoutRedirectUri("/authentication/logout-callback");
        });
        options.Clients.Add(new Duende.IdentityServer.Models.Client
        {
            ClientId = "WebApplication4.Integration",
            AllowedGrantTypes = { GrantType.ClientCredentials },
            ClientSecrets = { new Secret("MySecretValue".Sha256()) },
            AllowedScopes = { "WebApplication4.ServerAPI"}
        });
    });

This request will work:

POST /connect/token HTTP/1.1
Host: localhost:44397
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=WebApplication4.Integration&client_secret=MySecretValue&scope=WebApplication4.ServerAPI

However I want this client to have its own AllowedScopes. If I then change AllowedScopes = { "WebApplication4.ServerAPI"} to AllowedScopes = { "WebApplication4.IntegrationAPI"} and of course modifying the request.

Server then responds with:

{
    "error": "invalid_scope"
}

If I look at logging I get the following history:

info: Duende.IdentityServer.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: Duende.IdentityServer.Endpoints.TokenEndpoint for /connect/token
info: Duende.IdentityServer.Events.DefaultEventService[0]
      {
        "ClientId": "WebApplication4.Integration",
        "AuthenticationMethod": "SharedSecret",
        "Category": "Authentication",
        "Name": "Client Authentication Success",
        "EventType": "Success",
        "Id": 1010,
        "ActivityId": "80000009-0014-d600-b63f-84710c7967bb",
        "TimeStamp": "2022-09-22T09:30:31Z",
        "ProcessId": 17768,
        "LocalIpAddress": "::1:44397",
        "RemoteIpAddress": "::1"
      }
fail: Duende.IdentityServer.Validation.DefaultResourceValidator[0]
      Scope WebApplication4.IntegrationAPI not found in store or not supported by requested resource indicators.
fail: Duende.IdentityServer.Validation.TokenRequestValidator[0]
      Invalid scopes requested, {
        "ClientId": "WebApplication4.Integration",
        "GrantType": "client_credentials",
        "AuthorizationCode": "********",
        "RefreshToken": "********",
        "Raw": {
          "grant_type": "client_credentials",
          "client_id": "WebApplication4.Integration",
          "client_secret": "***REDACTED***",
          "scope": "WebApplication4.IntegrationAPI"
        }
      }
info: Duende.IdentityServer.Events.DefaultEventService[0]
      {
        "ClientId": "WebApplication4.Integration",
        "Endpoint": "Token",
        "GrantType": "client_credentials",
        "Error": "invalid_scope",
        "Category": "Token",
        "Name": "Token Issued Failure",
        "EventType": "Failure",
        "Id": 2001,
        "ActivityId": "80000009-0014-d600-b63f-84710c7967bb",
        "TimeStamp": "2022-09-22T09:30:31Z",
        "ProcessId": 17768,
        "LocalIpAddress": "::1:44397",
        "RemoteIpAddress": "::1"
      }

What I take with me is this:

Scope WebApplication4.IntegrationAPI not found in store or not supported by requested resource indicators.

I then looked at these guides:

https://github.com/IdentityServer/IdentityServer4/issues/4632#issuecomment-654685880

https://docs.duendesoftware.com/identityserver/v5/quickstarts/1_client_credentials/

I therefore added this code:

public static class Config
{
    public static IEnumerable<ApiScope> ApiScopes =>
        new List<ApiScope>
        {
        new ApiScope("WebApplication4.IntegrationAPI", "Integration API")
        };
}

and

services.AddIdentityServer()
    .AddInMemoryApiScopes(Config.ApiScopes)
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>...

This still gave me the same error.

I then added a new list with clients:

public static IEnumerable<Duende.IdentityServer.Models.Client> Clients =>
    new List<Duende.IdentityServer.Models.Client>
    {
        new Duende.IdentityServer.Models.Client
        {
            ClientId = "WebApplication4.Integration",
            AllowedGrantTypes = { GrantType.ClientCredentials },
            ClientSecrets = { new Secret("MySecretValue".Sha256()) },
            AllowedScopes = { "WebApplication4.IntegrationAPI" },
        }
    };

Removed the old client from AddApiAuthorization and used this code instead:

services.AddIdentityServer()
    .AddInMemoryApiScopes(Config.ApiScopes)
    .AddInMemoryClients(Config.Clients)
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => ...

This gave me a new error when requesting a token:

{
    "error": "invalid_client"
}

Logs:

info: Duende.IdentityServer.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: Duende.IdentityServer.Endpoints.TokenEndpoint for /connect/token
info: Duende.IdentityServer.Events.DefaultEventService[0]
      {
        "ClientId": "WebApplication4.Integration",
        "Category": "Authentication",
        "Name": "Client Authentication Failure",
        "EventType": "Failure",
        "Id": 1011,
        "Message": "Unknown client",
        "ActivityId": "8000000a-0016-e700-b63f-84710c7967bb",
        "TimeStamp": "2022-09-22T09:54:08Z",
        "ProcessId": 10676,
        "LocalIpAddress": "::1:44397",
        "RemoteIpAddress": "::1"
      }
fail: Duende.IdentityServer.Validation.ClientSecretValidator[0]
      No client with id 'WebApplication4.Integration' found. aborting

If I look at https://localhost:44397/.well-known/openid-configuration I only see WebApplication4.ServerAPI in scopes_supported no matter the configuration.

Describe the solution you’d like

I want to do it like this so that I can add a policy like this later:

services.AddAuthorization(options =>
{
    options.AddPolicy("IntegrationApiScope", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", "WebApplication4.IntegrationAPI");
    });
});

Meaning that I only want Client Credentials flow to get the scope WebApplication4.IntegrationAPI and I don’t want Authorization Code Grant, normal login flow via authorization_code, to have this scope or be able to request this scope.

Additional context

No response

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

0reactions
marinasundstromcommented, Oct 18, 2022

My Blazor app stopped working with a “invalid_scope”.

Source: https://github.com/marinasundstrom/todo-app

Here is the Identity Server log:

[identityservice_a6b737f7-2]: [13:37:21 Debug] Duende.IdentityServer.EntityFramework.Stores.ResourceStore
[identityservice_a6b737f7-2]: Found ["openid", "profile"] identity scopes in database
[identityservice_a6b737f7-2]:
[identityservice_a6b737f7-2]: [13:37:21 Debug] Duende.IdentityServer.EntityFramework.Stores.ResourceStore
[identityservice_a6b737f7-2]: Found ["myapi"] API resources in database
[identityservice_a6b737f7-2]:
[identityservice_a6b737f7-2]: [13:37:21 Debug] Duende.IdentityServer.EntityFramework.Stores.ResourceStore
[identityservice_a6b737f7-2]: Found ["myapi"] scopes in database
[identityservice_a6b737f7-2]:
[identityservice_a6b737f7-2]: [13:37:21 Error] Duende.IdentityServer.Validation.DefaultResourceValidator
[identityservice_a6b737f7-2]: Scope email not found in store or not supported by requested resource indicators.
[identityservice_a6b737f7-2]:
[identityservice_a6b737f7-2]: [13:37:21 Error] Duende.IdentityServer.Endpoints.AuthorizeEndpoint
[identityservice_a6b737f7-2]: Request validation failed

IdentityServer config:

    public static IEnumerable<ApiResource> ApiResources =>
        new ApiResource[]
        {
                // the api requires the role claim
                new ApiResource("myapi", "The Web Api", new[] { JwtClaimTypes.Name, JwtClaimTypes.PreferredUserName, JwtClaimTypes.Email, JwtClaimTypes.Role })
                {
                    Scopes = new string[] { "myapi" }
                }
        };

I started working again when I removed the scope “email” from “DefaultScopes” in appsettings.json in my Blazor app:

{
  "Local": {
    "Authority": "https://localhost:5041",
    "ClientId": "clientapp",
    "RedirectUri": "https://localhost:5021/authentication/login-callback",
    "ResponseType": "code",
    "DefaultScopes": [
      "openid",
      "profile",
      // "email",
      "myapi"
    ],
    "PostLogoutRedirectUri": "https://localhost:5021/"
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Duende.IdentityServer from Blazor WebAssembly App ...
Duende.IdentityServer from Blazor WebAssembly App protecting ASP.NET Core API using Client Credentials with custom allowed scope - invalid_scope.
Read more >
Protecting an API using Client Credentials
This first quickstart provides step by step instructions to set up IdentityServer in the most basic scenario: protecting APIs for server-to-server communication ...
Read more >
Protecting an API using Client Credentials
Protecting an API using Client Credentials. The following quickstart provides step by step instructions for various common Duende IdentityServer scenarios.
Read more >
Secure a hosted ASP.NET Core Blazor WebAssembly app ...
This article explains how to create a hosted Blazor WebAssembly solution that uses Duende Identity Server to authenticate users and API calls.  ......
Read more >
Securing API with Duende Server (Identity Server 6) - YouTube
In this video we will take an existing API application with authentication using . NET identity and we will modify to use Identity...
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