我使用IdentityModel.AspNetCore包使用客户端凭据流访问受保护的API
在启动时,我有以下配置
services.AddAccessTokenManagement(options =>
{
options.Client.Clients.Add("oauth", new ClientCredentialsTokenRequest
{
Address = Configuration.GetValue<string>("Endpoint"),
ClientId = Configuration.GetValue<string>("ClientId"),
ClientSecret = Configuration.GetValue<string>("ClientSecret"),
Scope = Configuration.GetValue<string>("Scope")
});
});
services.AddClientAccessTokenClient("client", configureClient: client =>
{
client.BaseAddress = new Uri(Configuration.GetValue<string>("ApiBaseUrl"));
});
在我的服务中,我得到了一个使用IHttpClientFactory
的客户端实例
var client = clientFactory.CreateClient("client");
这段代码运行良好,我可以访问API
我的问题是,当我扩展从clientFactory
获得的客户端实例时,其中的Authorization标头为null。
所以我很困惑这是怎么回事。
我预计它会设置带有承载令牌详细信息的Authorization标头值。
这是怎么回事?IdentityModel是如何设置承载令牌的
(API正确授权,似乎我更改了客户机密,它会给出401(
.NET允许您将DelegatingHandler
附加到HttpClient
以拦截和修改请求&响应。发送请求后,在通过网络实际发送之前,它会经过一堆处理程序。
public class MessageHandler1 : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
Debug.WriteLine("Process request");
// Call the inner handler.
var response = await base.SendAsync(request, cancellationToken);
Debug.WriteLine("Process response");
return response;
}
}
IdentityModel库的工作方式相同。它拦截请求,并在发送之前添加Authorization
处理程序。然后检查响应中是否存在HTTP 401
错误,刷新令牌并重复请求。
以下是它的工作原理(来源(:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
await SetTokenAsync(request, forceRenewal: false, cancellationToken);
var response = await base.SendAsync(request, cancellationToken);
// retry if 401
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
response.Dispose();
await SetTokenAsync(request, forceRenewal: true, cancellationToken);
return await base.SendAsync(request, cancellationToken);
}
return response;
}
至于似乎缺少的实际Authorization
标头,您可以在HttpResponseMessage.RequestMessage
属性中找到它。
来自文档(强调我的(:
此属性设置为导致此响应消息的请求消息。在使用HttpClient发送请求的情况下,此属性将指向导致最终响应的实际请求消息。请注意,此可能与用户在发送请求时提供的消息不同。如果由于重定向或身份验证而需要重新发送请求,通常会出现这种情况此属性可用于确定实际创建响应的URL(在重定向的情况下很有用(
进一步参考:
- https://www.stevejgordon.co.uk/httpclientfactory-aspnetcore-outgoing-request-middleware-pipeline-delegatinghandlers