Invalid Token - 观众“空”无效
Posted
技术标签:
【中文标题】Invalid Token - 观众“空”无效【英文标题】:Invalid Token - The audience 'empty' is invalid 【发布时间】: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 示例,但找不到解决方案。
我错过了什么?
【问题讨论】:
【参考方案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,我希望我能给你更多的支持 :)以上是关于Invalid Token - 观众“空”无效的主要内容,如果未能解决你的问题,请参考以下文章
Next.js:FetchError: invalid json response body Unexpected token < in JSON at position 0
Bearer error="invalid_token", error_description="之前的token无效
JWT Bearer 不断返回 401 状态 - Bearer error="invalid_token", error_description="签名无效"
What is the best way to handle Invalid CSRF token found in the request when session times out in Spr