如何在IdentityServer 4中使用’refresh_token’?
我正在使用.net核心与IdentityServer 4.我有一个Web api,以及一个访问api上安全端点的MVC应用程序。 它与IdentityServer快速入门的设置非常相似:
https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/6_AspNetIdentity
我发现我的access_tokens
即将到期,我想了解如何重新协商refresh_tokens
。
以下面的代码为例(摘自此处的快速入门):
public async Task CallApiUsingUserAccessToken() { var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token"); var client = new HttpClient(); client.SetBearerToken(accessToken); var content = await client.GetStringAsync("http://localhost:5001/identity"); ViewBag.Json = JArray.Parse(content).ToString(); return View("json"); }
如果access_token
已过期,它将失败并返回401响应。 是否有使用refresh_token
重新协商access_token
的内置机制?
系统中没有用于刷新access_token
的内置版本。 但是,您可以使用IdentityModel
包来请求带有refresh_token
的新access_token
。
Client
具有属性AllowOfflineAccess
,您应在IdentityServer AllowOfflineAccess
其设置为true。 请注意,这不适用于隐式/客户端凭据流。
- 始终在调用受保护资源之前刷新access_token
- 通过检查当前
access_token
的生命周期并使用refresh_token
(个人首选项)请求新的access_token
来检查当前access_token
是否即将过期 - 等待API使用
refresh_token
返回401广告请求新的access_token
在此代码之前,您可以检查access_token
生存期和/或在请求新的access_token
之前将此代码包装在服务中
var discoveryResponse = await DiscoveryClient.GetAsync("IdentityServer url"); if (discoveryResponse.IsError) { throw new Exception(discoveryResponse.Error); } var tokenClient = new TokenClient(discoveryResponse.TokenEndpoint, "ClientId", "ClientSecret"); // This will request a new access_token and a new refresh token. var tokenResponse = await tokenClient.RequestRefreshTokenAsync(await httpContext.Authentication.GetTokenAsync("refresh_token")); if (tokenResponse.IsError) { // Handle error. } var oldIdToken = await httpContext.Authentication.GetTokenAsync("id_token"); var tokens = new List { new AuthenticationToken { Name = OpenIdConnectParameterNames.IdToken, Value = oldIdToken }, new AuthenticationToken { Name = OpenIdConnectParameterNames.AccessToken, Value = tokenResult.AccessToken }, new AuthenticationToken { Name = OpenIdConnectParameterNames.RefreshToken, Value = tokenResult.RefreshToken } }; var expiresAt = DateTime.UtcNow.AddSeconds(tokenResult.ExpiresIn); tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) }); // Sign in the user with a new refresh_token and new access_token. var info = await httpContext.Authentication.GetAuthenticateInfoAsync("Cookies"); info.Properties.StoreTokens(tokens); await httpContext.Authentication.SignInAsync("Cookies", info.Principal, info.Properties);
取自并稍加修改: 来源