过期时更新令牌的常用方法是使用过期数据,来自带有令牌响应的令牌端点。您可以缓存该时间间隔的令牌,每次需要设置承载时,您首先尝试从缓存中获取它。当令牌过期时,缓存返回 null,因此您请求一个新的令牌并再次缓存它。
请参阅基于Dominick Baier的文章的示例。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;
}
}