IdentityServer4:服务到服务调用无法找到受众

IdentityServer4 : Service to service call fails to find Audience

我正在尝试使用 IdentityServer4 对 Micoservices 架构的用户进行身份验证。当我尝试从我的 Web 应用程序控制器调用另一个 Web API 服务时,调用在 Web API 服务上失败,控制台上显示如下消息:

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: 
IDX10214: Audience validation failed. 
Audiences: 'null/resources'. Did not match: validationParameters.ValidAudience: 'hierarchy' or validationParameters.ValidAudiences: 'null'.

我的调用链如下所示:

[User] --> [ASP.Net core MVC: Web App ]--> [ASP.Net core MVC: Web Api ]

我使用具有以下配置的 IdentityServer4 创建了一个 Identity server

API资源

new ApiResource("hierarchy", "Hierarchy Configuration API"),
new ApiResource("deviceconfiguration", "Device Configuration API"),

客户端

new Client
{
   ClientId = "system.health.check",
   ClientName = "System health check client",
   AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

   ClientSecrets = { new Secret("secret".Sha256()) },
   AllowedScopes = {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "healthcheck"
                    },

    RedirectUris = { "http://localhost:5100/signin-oidc",  "http://localhost:5103/signin-oidc",},
    PostLogoutRedirectUris = { "http://localhost:5100/signout-callback-oidc" },
}

服务 - 启动

services.AddIdentityServer(x => x.IssuerUri = "null")
        .AddSigningCredential(Certificate.Certificate.Get())
        .AddTemporarySigningCredential()
        .AddInMemoryIdentityResources(Config.GetIdentityResources())
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients())
        .AddTestUsers(Config.GetUsers());

[ASP.Net 核心 MVC:Web 应用]

我的选项设置如下:

"OpenIdConnectOptions": {
  "AuthenticationScheme": "oidc",
  "SignInScheme": "Cookies",
  "Authority": "http://localhost:5000",
  "RequireHttpsMetadata": false,
  "ClientId": "system.health.check",
  "ClientSecret": "secret",
  "ResponseType": "code id_token",
  "GetClaimsFromUserInfoEndpoint": true,
  "SaveTokens": true
}

启动时的配置代码如下所示:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
     AuthenticationScheme = "Cookies"
});

var option1 = new OpenIdConnectOptions();
Configuration.GetSection("Security:OpenIdConnectOptions").Bind(option1);
app.UseOpenIdConnectAuthentication(option1);

到目前为止效果很好,我可以看到当用户未通过身份验证时,他被定向到身份服务器并且令牌有问题。

现在的问题是,我希望将此服务的调用路由到另一个 Web API service,该服务也受到 say hierarchy 范围的保护,如下所示:

服务到服务调用

var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");
var requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5103/api/Hierarchy/22");
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); 

var _client = new HttpClient();
var response = await _client.SendAsync(requestMessage);
return await response.Content.ReadAsStringAsync();

[ASP.Net 核心 MVC:Web Api]

启动设置与我的其他服务相同,但由于这是资源服务,所以我的配置不同:

"IdentityServerAuthenticationOptions": {
  "Authority": "http://localhost:5000",
  "RequireHttpsMetadata": false,
  "ApiName": "hierarchy",
  "AllowedScopes": [
    "openid",
    "hierarchy"
  ]

启动时的配置代码如下所示:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
     AuthenticationScheme = "Cookies"
});

var option2 = new IdentityServerAuthenticationOptions();
Configuration.GetSection("Security:IdentityServerAuthenticationOptions").Bind(option2);
app.UseIdentityServerAuthentication(option2);

现在的问题是调用没有 return 任何东西,在这个服务的控制台上我看到一个日志说:

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: 'null/resources'. Did not match: validationParameters.ValidAudience: 'hierarchy' or validationParameters.ValidAudiences: 'null'.
   at Microsoft.IdentityModel.Tokens.Validators.ValidateAudience(IEnumerable`1 audiences, SecurityToken securityToken, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwt, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext() 

当我解码 [Web App] 上的访问令牌时,这就是我所看到的

{
  "nbf": 1501764330,
  "exp": 1501767930,
  "iss": "null",
  "aud": "null/resources",
  "client_id": "system.health.check",
  "sub": "2",
  "auth_time": 1501764327,
  "idp": "local",
  "scope": [
    "openid",
    "profile"
  ],
  "amr": [
    "pwd"
  ]
}

所以它显然缺少 Audience 以及范围 healthcheck 关于为什么它缺少 Audience 或我在这里缺少什么的任何想法?

假设您的 api 名称是 "hierarchy",请尝试在客户端配置的允许范围中传递它。这里:

new Client
{
   ClientId = "system.health.check",
   ClientName = "System health check client",
   AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

   ClientSecrets = { new Secret("secret".Sha256()) },
   AllowedScopes = {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        "healthcheck" <------
                    },

    RedirectUris = { "http://localhost:5100/signin-oidc",  "http://localhost:5103/signin-oidc",},
    PostLogoutRedirectUris = { "http://localhost:5100/signout-callback-oidc" },
}

可以在healthcheck

之后添加