Invalid Token - The audience 'empty' is invalid

余生长醉 提交于 2021-02-10 15:41:56

问题


I have the following Identity Server 4 configuration on ASP.NET Core 3.1 projects:

services
  .AddIdentityServer(y => {
    y.Events.RaiseErrorEvents = true;
    y.Events.RaiseInformationEvents = true;
    y.Events.RaiseFailureEvents = true;
    y.Events.RaiseSuccessEvents = true;
  })
  .AddDeveloperSigningCredential()
  .AddInMemoryPersistedGrants()
  .AddInMemoryIdentityResources(Config.IdentityResources())
  .AddInMemoryApiResources(Config.ApiResources())
  .AddInMemoryApiScopes(Config.GetApiScopes())
  .AddInMemoryClients(Config.Clients)
  .AddProfileService<ProfileService>()
  .AddAspNetIdentity<User>();

The Config is the following:

public static class Config {

  public static List<ApiResource> ApiResources() {
    return new List<ApiResource> { 
      new ApiResource("api", "API Resource")
    };
  }

  public static List<ApiScope> ApiScopes() {
    return new List<ApiScope> { 
      new ApiScope("api", "API Scope") 
    };
  }

  public static List<IdentityResource> IdentityResources() {
    return new List<IdentityResource> { 
      new IdentityResources.OpenId(),
      new IdentityResources.Profile(),
      new IdentityResources.Email() 
    };
  }   

  public static List<Client> Clients() {
    return new List<Client> { 
      new Client {
        ClientId = "mvc",
        ClientName = "MVC Client",
        AllowedGrantTypes = GrantTypes.ClientCredentials,
        ClientSecrets = { new Secret("Secret".Sha256()) }
        AllowedScopes = { 
          IdentityServerConstants.StandardScopes.OpenId,
          IdentityServerConstants.StandardScopes.Profile, 
          IdentityServerConstants.StandardScopes.Email, 
          IdentityServerConstants.StandardScopes.OfflineAccess,
          "api"
        }         
      }
    };
  }

}

And on the API I have:

  services
    .AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
    .AddIdentityServerAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme, x => {
      x.ApiName = "api";
      x.ApiSecret = "Secret"
      x.Authority = Config.AuthorityUrl;
      x.RequireHttpsMetadata = true;
      x.EnableCaching = true;
      x.CacheDuration = TimeSpan.FromMinutes(20);
    });

I called one API endpoint using Insomnia client with OAuth2:

I was able to get the Access token but when calling the API I got the error:

Bearer error="invalid_token", error_description="The audience 'empty' is invalid"

I checked the Access token using JWT and I got the following:

Header

{
  "alg": "HS256",
  "kid": "A1042705E52832C676596F36BB1898AB",
  "typ": "at+jwt"
}

Payload

{
  "nbf": 1598478410,
  "exp": 1598482010,
  "iss": "https://localhost:5000",
  "client_id": "mvc",
  "jti": "23525FF997FD4D71E13C786A7AD07B5D",
  "iat": 1598478410,
  "scope": [
    "api"
  ]
}

The aud is missing. But do I need it? After reading the IS4 docs I tried adding:

.AddIdentityServer(y => {
  y.EmitStaticAudienceClaim = true;

Now the Access token has aud field but its value is not api. Shouldn't it be?

"aud": "https://localhost:5000/resources"

When calling the API I now get the error:

Bearer error="invalid_token", error_description="The audience 'https://localhost:5000/resources' is invalid"

I read the docs and IS4 examples but couldn't find a solution.

What am I missing?


回答1:


What you need to is to connect the ApiScope with the APIRespource to get api to be the desired scope. The https://localhost:5000/resources aud claim is a generic audience when the scopes and api's are not "connecteted".

In your API definition you need to do something like in this example (Look at the Scopes property below)

var invoiceApi = new ApiResource()
{
    Name = "invoice",   //This is the name of the API
    Description = "This is the invoice Api-resource description",
    Enabled = true,
    DisplayName = "Invoice API Service",
    Scopes = new List<string> { "shop.admin", "shop.employee" },
};

See this link for details about the generic resource scope that is ussued.

It says:

When using the scope-only model, no aud (audience) claim will be added to the token, since this concept does not apply. If you need an aud claim, you can enable the EmitStaticAudience setting on the options. This will emit an aud claim in the issuer_name/resources format. If you need more control of the aud claim, use API resources.

You can try to set the EmitStaticAudience option to false.

You can also ignore the two audiences in the token.



来源:https://stackoverflow.com/questions/63606288/invalid-token-the-audience-empty-is-invalid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!