在以下代码中,我希望续订访问令牌(如果已过期)。但是没有任何效果。我尝试使用断点在行返回响应上进行调试,但该断点不会触发。
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
response = await base.SendAsync(request, cancellationToken);
if (response.StatusCode != HttpStatusCode.Unauthorized)
return response;
var tokenResponse = _tokenGenerator.GetAccessToken(accessTokenInfo).Result;
if (tokenResponse != null)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse);
response = await base.SendAsync(request, cancellationToken);
}
return response;
}
答案 0 :(得分:1)
在过期时更新令牌的通常方法是使用过期数据,该数据来自令牌端点以及令牌响应。您可以在该间隔内缓存令牌,并且每次需要设置载体时,都首先尝试从缓存中获取令牌。当令牌过期时,缓存将返回null,因此您请求一个新令牌并再次对其进行缓存。
请参阅基于Dominick Baier的the article的示例。如果尚未完成,则需要安装IdentityModel
nuget软件包。
public class TokenClientOptions
{
public string Address { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
}
public class TokenClient
{
private const string AccessTokenCacheKey = "access_token";
public HttpClient Client { get; }
public TokenClientOptions Options { get; }
public ILogger<TokenClient> Logger { get; }
public IDistributedCache Cache { get; }
public TokenClient(HttpClient client, IOptions<TokenClientOptions> options,
IDistributedCache cache,
ILogger<TokenClient> logger)
{
Client = client;
Options = options.Value;
Cache = cache;
Logger = logger;
}
public async Task<string> GetToken()
{
var token = Cache.GetString(AccessTokenCacheKey);
if (token != null)
return token;
var response = await Client.
RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
{
Address = Options.Address,
ClientId = Options.ClientId,
ClientSecret = Options.ClientSecret
});
Cache.SetString(AccessTokenCacheKey, response.AccessToken,
new DistributedCacheEntryOptions()
{AbsoluteExpirationRelativeToNow =
TimeSpan.FromSeconds(response.ExpiresIn)});
return response.AccessToken;
}
}
public static class Extensions
{
public static void AddTokenClient(this IServiceCollection services) {
services.Configure<TokenClientOptions>(options =>
{
options.Address = "https://demo.identityserver.io/connect/token";
options.ClientId = "client";
options.ClientSecret = "secret";
});
services.AddDistributedMemoryCache();
services.AddHttpClient<TokenClient>();
}
}
然后在您的Startup.ConfigureServices
中添加:services.AddTokenClient();
之后,您可以将TokenClient
注入API控制器并像上面的示例中一样使用它:
public class TestController : Controller
{
public TokenClient TokenClient { get; }
public TestController(TokenClient tokenClient) => TokenClient = tokenClient;
public async Task<HttpResponseMessage> Index()
{
var request = new HttpRequestMessage(
HttpMethod.Get, "https://demo.identityserver.io/api/test");
var accessToken = await TokenClient.GetToken();
request.SetBearerToken(accessToken);
var client = HttpClientFactory.Create();
var response = await client.SendAsync(request, new CancellationToken());
return response;
}
}