看起来你需要委托处理程序 https://www.stevejgordon.co.uk/httpclientfactory-aspnetcore-outgoing-request-middleware-pipeline-delegatinghandlers。简而言之,您可以“拦截”您的 http 请求并添加授权标头,然后尝试执行它,如果令牌无效,则刷新令牌并重试一次。就像是:
public class AuthenticationDelegatingHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = await GetTokenAsync();
request.Headers.Authorization = new AuthenticationHeaderValue(token.Scheme, token.AccessToken);
var response = await base.SendAsync(request, cancellationToken);
if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden)
{
token = await RefreshTokenAsync();
request.Headers.Authorization = new AuthenticationHeaderValue(token.Scheme, token.AccessToken);
response = await base.SendAsync(request, cancellationToken);
}
return response;
}
}
您可以在 Startup.cs 中注册此委托处理程序,如下所示:
services.AddTransient<AuthenticationDelegatingHandler>();
services.AddHttpClient("MySecuredClient", client =>
{
client.BaseAddress = new Uri("https://baseUrl.com/");
})
.AddHttpMessageHandler<AuthenticationDelegatingHandler>();
并像这样使用:
var securedClient = _httpClientFactory.CreateClient("MySecuredClient");
securedClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "v2/relativeUrl"));
关于在 appsetting.json 中存储刷新令牌。我认为这不是一个好主意,因为刷新令牌没有过期时间。如果您第一次可以使用凭据获取新令牌,请使用它,然后将刷新令牌存储在内存中以供进一步刷新。
Here https://github.com/gao-artur/AuthenticationHandler您可以了解我如何管理客户端凭据令牌刷新并尝试使其适合您的场景。
Update:
Here https://identitymodel.readthedocs.io/en/latest/aspnetcore/overview.html您可以找到相同的想法,但由专业人员实施并可在nuget https://www.nuget.org/packages/IdentityModel.AspNetCore。使用方法非常简单:
services.AddAccessTokenManagement(options =>
{
options.Client.Clients.Add("identityserver", new ClientCredentialsTokenRequest
{
Address = "https://demo.identityserver.io/connect/token",
ClientId = "m2m.short",
ClientSecret = "secret",
Scope = "api" // optional
});
});
services.AddHttpClient<MyClient>(client =>
{
client.BaseAddress = new Uri("https://demo.identityserver.io/api/");
})
.AddClientAccessTokenHandler();
请求发送者MyClient
将始终拥有有效的不记名令牌。刷新自动执行。