C# 为什么IdentityServer4生成的访问令牌始终无效?
我正在尝试在asp.net core 3.1上使用IdentityServer 4设置一个相当基本的identity oAuth服务器。我已经创建了一个基本项目,并使用inmemory配置 我可以请求和接收一个承载令牌(客户端凭证流),但每当我打自省电话时,我都会收到401响应。我怀疑这与令牌本身有关-尝试使用一些在线网站验证它似乎总是显示无效令牌 我的代码Starup.cs:C# 为什么IdentityServer4生成的访问令牌始终无效?,c#,asp.net-core,oauth,identityserver4,C#,Asp.net Core,Oauth,Identityserver4,我正在尝试在asp.net core 3.1上使用IdentityServer 4设置一个相当基本的identity oAuth服务器。我已经创建了一个基本项目,并使用inmemory配置 我可以请求和接收一个承载令牌(客户端凭证流),但每当我打自省电话时,我都会收到401响应。我怀疑这与令牌本身有关-尝试使用一些在线网站验证它似乎总是显示无效令牌 我的代码Starup.cs: services.AddIdentityServer() .A
services.AddIdentityServer()
.AddInMemoryApiScopes(InMemoryConfig.GetApiScopes())
.AddInMemoryApiResources(InMemoryConfig.GetApiResources())
.AddInMemoryIdentityResources(InMemoryConfig.GetIdentityResources())
.AddTestUsers(InMemoryConfig.GetUsers())
.AddInMemoryClients(InMemoryConfig.GetClients())
.AddDeveloperSigningCredential();
在memoryconfig.cs中:
public static IEnumerable<Client> GetClients() =>
new List<Client>
{
new Client
{
ClientId = "myclient",
ClientSecrets = new [] { new Secret("dev-$he turned me into a newt!".Sha512()) },
AllowedGrantTypes = GrantTypes.ClientCredentials,
AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId,
"read",
"write",
"update",
"delete"}
}
};
public static IEnumerable<ApiScope> GetApiScopes() =>
new List<ApiScope> {
new ApiScope("read", "read data"),
new ApiScope("write", "write data"),
new ApiScope("update", "update data"),
new ApiScope("delete", "delete data")
};
public static IEnumerable<ApiResource> GetApiResources() =>
new List<ApiResource>
{
new ApiResource("partnerservices", "Partner Services")
{
ApiSecrets = new [] {new Secret("PSSecret")},
Scopes = { "read","write","update","delete"}
},
new ApiResource("coreservices", "Core Services")
{
Scopes = { "read","write","update","delete"}
},
new ApiResource("mysite", "My Site")
{
Scopes = { "read","write","update","delete"}
}
};
…下面是从“jwks_uri”返回的公钥信息:https://localhost:44311/.well-我的发现文档中的已知/openid配置/jwks:
{"keys":[{"kty":"RSA","use":"sig","kid":"10BFC6495366E457669C6A37EA973B00","e":"AQAB","n":"0Zq2wamtiFtqhNNqlY4rYyC1nbO1hB1ztXIhYJc7tjhhpsyViXyWlKiD8cORmHieO8sH4ZSXCeQbYV7u1nXI7SG28ul9kozpUO7M9vf1nOv50o9mZg_BOyMFnTgcDMN6zjT1IWM9K5NY-2D7jSZvxQo4GNwWr2SpytRXLYAgWSHgj3wDarZIXfHKmIRSYvS8L6d_2G0dbxWD699VQMRz0WBjRR6qwhlXc4-4dSeBfvrioWf0DA6LD2NGNA1oP1XWuV_Htkh2Ay5Ck4AyUc3xbC4TVI3SpuhYMK_3zuHwmnzA1L4SyXnHG963hXpbDSUtu01i3YTK2v5MterR9PFWzQ","alg":"RS256"}]}
如果你还在读这篇文章,谢谢!问题是我不能使用该承载令牌进行后续的内省调用,也不能使用任何在线验证器(例如jwt.io)验证该令牌
我错过了什么
为了完整起见,以下是我的自省电话:
> POST /connect/introspect HTTP/2
> Host: localhost:44311
> authorization: Basic ZXRyYWMtY2xhcmlmeTpldHJhY2Rldi0kaGUgdHVybmVkIG1lIGludG8gYSBuZXd0IQ==
> user-agent: insomnia/2020.4.2
> content-type: application/x-www-form-urlencoded
> accept: */*
> content-length: 796
| token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjEwQkZDNjQ5NTM2NkU0NTc2NjlDNkEzN0VBOTczQjAwIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MDQ2ODkxMTgsImV4cCI6MTYwNDY5MjcxOCwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NDQzMTEiLCJhdWQiOlsiZXRyYWMtcGFydG5lcnNlcnZpY2VzIiwiZXRyYWMtY29yZXNlcnZpY2VzIiwiZXRyYWMtbGlua2QiXSwiY2xpZW50X2lkIjoiZXRyYWMtY2xhcmlmeSIsImp0aSI6IjNGQzQ0NzE4QTAyMzcyRUFBOUFDMDUzOEQyNjQyMDk5IiwiaWF0IjoxNjA0Njg5MTE4LCJzY29wZSI6WyJkZWxldGUiLCJyZWFkIiwidXBkYXRlIiwid3JpdGUiXX0.iDl8MEgqRcgFdg3T-rST9jTIxGJfwMtGQ-a6nSAxOadqs8P0EM_UcCYVwKhuzjNM4uORbrhsD5XDB2wMtgMEaSgNdKlH5NA2OTRkftFAKyii2M0ihQL06rN1KVURKySK4d38pezuQxZ48blDaro5ae8RUxMOkRlsPwX6e6LBKeJ2MkqmKcj6AJ1b0sDkJpdgagy4gjvBGWcQOAf_TuEobaWBEKEdzF_gM0a321PDFayCTuezc7bIYN5eq4VQL3-PINbOq72Cashjmi4BCNF0sV-gKq1blDMEZ6UcN-jGOUaaEtvh36H8bHw2H-mY1535tPpX4PzpE_zB6mtHvpJScA
这一切看起来都很好,我使用Flurl.httpnugetp包进行手动内省调用的代码如下所示:
/// <summary>
/// Introspect an access token
/// </summary>
/// <param name="accessToken">The received access token</param>
/// <param name="apiName">The name of this API-Resource as defined in Identity Server</param>
/// <param name="apiSecret">the API secret as defined in the API-Resource</param>
private void IntrospectToken(string accessToken, string apiName, string apiSecret)
{
//Get the Introspection endpoint URL
var url = new Url(openIdConfig.IntrospectionEndpoint).WithBasicAuth(apiName, apiSecret);
var introspectionResult = url.PostUrlEncodedAsync(new
{
token = accessToken
}).ReceiveString().Result;
//Console.WriteLine("\r\nintrospection Result");
//Console.WriteLine(introspectionResult);
}
//
///内省访问令牌
///
///接收到的访问令牌
///Identity Server中定义的此API资源的名称
///API资源中定义的API机密
私有void IntrospectToken(string accessToken、string apiName、string apiSecret)
{
//获取内省端点URL
var url=新的url(openIdConfig.IntrospectionEndpoint).WithBasicAuth(apiName,apiSecret);
var introspectionResult=url.PostUrlEncodedAsync(新
{
令牌=访问令牌
}).ReceiveString().Result;
//Console.WriteLine(“\r\n透视结果”);
//Console.WriteLine(内省结果);
}
也许它可以提供一些线索?关于jwt.io的验证。实际上,结果是。很可能是您在公钥字段中输入了密钥数组,而不是唯一的元素
接下来,您不必对JWT使用内省。它们用于就地验证。请阅读以了解更多详细信息。谢谢您的回答。在我的情况下,需要验证签名的上下文没有访问任何工具的权限。该工具集可以发出http请求,但无法验证签名它本身。另一种选择是编写我自己的端点,该工具集可以点击该端点来验证签名-但似乎内省端点已经用于此目的。那么,为什么我必须编写我自己的端点?无论如何,再次感谢!我不确定我在做什么,这使得它看起来没有被验证…无论如何,我认为401错误对于我的内省请求并不是说令牌无效。我认为它只是在验证令牌之前未能授权请求。我无法理解这一点。
/// <summary>
/// Introspect an access token
/// </summary>
/// <param name="accessToken">The received access token</param>
/// <param name="apiName">The name of this API-Resource as defined in Identity Server</param>
/// <param name="apiSecret">the API secret as defined in the API-Resource</param>
private void IntrospectToken(string accessToken, string apiName, string apiSecret)
{
//Get the Introspection endpoint URL
var url = new Url(openIdConfig.IntrospectionEndpoint).WithBasicAuth(apiName, apiSecret);
var introspectionResult = url.PostUrlEncodedAsync(new
{
token = accessToken
}).ReceiveString().Result;
//Console.WriteLine("\r\nintrospection Result");
//Console.WriteLine(introspectionResult);
}