【问题标题】:Invalid Token - The audience 'empty' is invalidInvalid Token - 观众“空”无效
【发布时间】:2020-12-15 18:21:17
【问题描述】:

我在 ASP.NET Core 3.1 项目中有以下 Identity Server 4 配置:

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>();

Config 如下:

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"
        }         
      }
    };
  }

}

在我拥有的 API 上:

  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);
    });

我使用 Insomnia 客户端和 OAuth2 调用了一个 API 端点:

我能够获取访问令牌,但在调用 API 时出现错误:

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

我使用 JWT 检查了访问令牌,得到以下信息:

标题

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

有效载荷

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

aud 丢失。但是我需要吗?阅读 IS4 文档后,我尝试添加:

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

现在访问令牌有aud 字段,但它的值不是api。不应该吗?

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

现在调用 API 时出现错误:

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

我阅读了文档和 IS4 示例,但找不到解决方案。

我错过了什么?

【问题讨论】:

    标签: asp.net-core jwt identityserver4 asp.net-core-3.1


    【解决方案1】:

    您需要做的是将 ApiScope 与 APIRespource 连接起来,以使 api 成为所需的范围。当范围和 api 没有“连接”时,https://localhost:5000/resources aud 声明是通用受众。

    在您的 API 定义中,您需要执行与此示例类似的操作(查看下面的 Scopes 属性)

    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" },
    };
    

    有关所使用的通用资源范围的详细信息,请参阅此link

    上面写着:

    使用仅限范围模型时,不会添加任何 aud(受众)声明 到令牌,因为这个概念不适用。如果你需要一个 aud 声明,您可以在选项上启用 EmitStaticAudience 设置。 这将以 issuer_name/resources 格式发出 aud 声明。如果 您需要更多地控制 aud 声明,使用 API 资源。

    您可以尝试将 EmitStaticAudience 选项设置为 false

    您也可以忽略令牌中的两个受众。

    【讨论】:

    • 我听从了你的建议,它奏效了,但发生了一些奇怪的事情。现在令牌中的aud 是:“aud”:[“api”,“localhost:5000/resources”]。 “localhost:5000/resources”不应该从 aud 中消失,因为现在 api 资源和范围已连接?
    • 更新了我的答案,希望答案可以接受。 /resources 受众是版本 4.x 或 IdentityServer4 中的新事物
    • 感谢您的澄清。我只是标记为答案。这对我很有帮助!
    • @ToreNestenius,我希望我能给你更多的支持 :)
    猜你喜欢
    • 2017-12-08
    • 2019-01-03
    • 2021-02-06
    • 1970-01-01
    • 2020-10-20
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    相关资源
    最近更新 更多