I'm using IdentityServer4, following the documentation at https://identityserver4.readthedocs.io/en/latest/quickstarts/1_client_credentials.html
But I am getting an invalid_scope error in the client that uses IdentityModel when requesting a token with client credentials.
It's possible I missed some step, but I've reviewed it several times.
The strange thing is that the identity server endpoint shows the following logs:
Invalid scopes requested, {"ClientId": "client", "ClientName": null, "GrantType": "client_credentials", "Scopes": null, "AuthorizationCode": null, "RefreshToken": null, "UserName": null, "AuthenticationContextReferenceClasses": null, "Tenant": null, "IdP": null, "Raw": {"grant_type": "client_credentials", "scope": "api1", "client_id": "client", "client_secret": "***REDACTED***"}, "$type": "TokenRequestValidationLog"}
Isn't strange that Scopes is null and later on scope has the api1 value?
I am using in memory values.
public static class Config
{
public static IEnumerable<IdentityResource> Ids =>
new IdentityResource[]
{
new IdentityResources.OpenId()
};
public static IEnumerable<ApiResource> Apis =>
new List<ApiResource>
{
new ApiResource("api1", "My Api")
};
public static IEnumerable<Client> Clients =>
new List<Client>
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = { "api1" }
}
};
}
and
public void ConfigureServices(IServiceCollection services)
{
// uncomment, if you want to add an MVC-based UI
//services.AddControllersWithViews();
var builder =
services
.AddIdentityServer()
.AddInMemoryApiResources(Config.Apis)
.AddInMemoryClients(Config.Clients)
.AddInMemoryIdentityResources(Config.Ids);
// not recommended for production - you need to store your key material somewhere secure
builder.AddDeveloperSigningCredential();
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// uncomment if you want to add MVC
//app.UseStaticFiles();
//app.UseRouting();
app.UseIdentityServer();
// uncomment, if you want to add MVC
//app.UseAuthorization();
//app.UseEndpoints(endpoints =>
//{
// endpoints.MapDefaultControllerRoute();
//});
}
I can see the well known configuration, although it does not mention api1 as supported scopes.
This is the client
var client = new HttpClient();
var discovery =
await client.GetDiscoveryDocumentAsync("https://localhost:5001");
if (discovery.IsError)
{
await Console.Out.WriteLineAsync("Discovery error");
return;
}
// request token
var clientCredentialsTokenRequest =
new ClientCredentialsTokenRequest
{
Address = discovery.TokenEndpoint,
ClientId = "client",
ClientSecret = "secret",
Scope = "api1"
};
var tokenResponse =
await client.RequestClientCredentialsTokenAsync(clientCredentialsTokenRequest);
Am I missing any additional thing to have the most basic sample work?
UPDATE 1:
Ok, I have downgraded Identity Server to 3.1.3 and it works as it is. For the version Identity Server 4.0.0 something must have changed. Will investigate there.