Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am trying to secure a .NET 5.0 Web API with OAuth Client Credentials flow.

My Client is requesting a token from the IdentityServer4 instance and supplying it to the API. The API is then returning a 401 error when I access and endpoint. I notice the following header: WWW-Authenticate header contains Bearer error="invalid_token", error_description="The audience 'empty' is invalid"

Which suggests my JWT does not contain the audience paramater.

My JWT request code looks like the following:

var tokenResponseType = await serverClient.RequestClientCredentialsTokenAsync(new                 
    ClientCredentialsTokenRequest
    {
        Address = discoveryDocument.TokenEndpoint,
        ClientId = "client_id",
        ClientSecret = "client_secret",
        Scope = "ApiOne",
    });

The code to validate the Token is here:

services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", config =>
    {
        config.Authority = "https://localhost:44335/";
        config.Audience = "ApiOne";
        config.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidateActor = true,
            ValidateLifetime = true,
            ValidateAudience = true,
            ValidateIssuerSigningKey = true
        };
        config.RequireHttpsMetadata = false;
     });

I believe the JWT token should contain the audience parameter. When I request the JWT I can't find a way to set the audience parameter.

I've used jwt.io to debug my JWT token and this confirms the audience value is not set. I expected setting the Scope on the request would do this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.5k views
Welcome To Ask or Share your Answers For Others

1 Answer

What is lacking is the ApiScope and ApiResource configuration in IdentityServer.

First you need an ApiScope defined, like:

new ApiScope(name: "ApiOneScope",
            displayName:"You can manage the ApiOne system.",
            userClaims: new List<string>{ });

The ApiScope is a scope that the client can request access to.

then you need a ApiResource defined like:

new ApiResource()
{
    Name = "ApiOne",   
    DisplayName = "Orders API Service",
    Scopes = new List<string> { "ApiOneScope" },
};

The ApiResource is the actual Api, that end up in the audience claim when the clients requests the scope named ApiOneScope.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...