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
之后添加
我正在尝试使用 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
之后添加