C# 如何使用';刷新令牌';在IdentityServer 4中?
我正在使用带有IdentityServer 4的.net core。我有一个Web api和一个MVC应用程序,可以访问api上的安全端点。它的设置与IdentityServer quickstart非常相似: 我发现我的C# 如何使用';刷新令牌';在IdentityServer 4中?,c#,identityserver4,C#,Identityserver4,我正在使用带有IdentityServer 4的.net core。我有一个Web api和一个MVC应用程序,可以访问api上的安全端点。它的设置与IdentityServer quickstart非常相似: 我发现我的access\u令牌即将过期,我想了解如何重新协商refresh\u令牌 以以下代码为例(摘自quickstart): public异步任务CallApiUsingUserAccessToken() { var accessToken=await-HttpContext.Au
access\u令牌
即将过期,我想了解如何重新协商refresh\u令牌
以以下代码为例(摘自quickstart):
public异步任务CallApiUsingUserAccessToken()
{
var accessToken=await-HttpContext.Authentication.GetTokenAsync(“访问令牌”);
var client=新的HttpClient();
client.SetBearerToken(accessToken);
var content=await client.GetStringAsync(“http://localhost:5001/identity");
Json=JArray.Parse(content.ToString();
返回视图(“json”);
}
如果
access\u令牌
已过期,它将失败并响应401。是否有使用刷新\u令牌重新协商访问\u令牌的内置机制?没有用于刷新访问\u令牌的内置系统。但是,您可以使用IdentityModel
包请求使用refresh\u令牌的新access\u令牌
客户端
有一个属性AllowOfflineAccess
,您应该在IdentityServer中将该属性设置为true。请注意,这对隐式/客户端凭据流不起作用
- 在调用受保护资源之前,始终刷新access_令牌
- 通过检查当前的
access\u令牌的生存期并使用refresh\u令牌请求一个新的access\u令牌
(个人偏好),检查当前的access\u令牌
是否即将过期
- 等待API返回401AD请求一个新的
access\u令牌
和refresh\u令牌
在此代码之前,您可以检查access\u令牌
生存期和/或在请求新的access\u令牌
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<AuthenticationToken>
{
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);
var discoveryResponse=wait DiscoveryClient.GetAsync(“IdentityServer url”);
如果(发现响应IsError)
{
抛出新异常(discoveryResponse.Error);
}
var tokenClient=new tokenClient(discoveryResponse.TokenEndpoint,“ClientId”,“ClientSecret”);
//这将请求一个新的访问令牌和一个新的刷新令牌。
var-tokenResponse=await-tokenClient.RequestRefreshTokenAsync(await-httpContext.Authentication.GetTokenAsync(“刷新令牌”);
if(tokenResponse.IsError)
{
//处理错误。
}
var oldIdToken=await-httpContext.Authentication.GetTokenAsync(“id_-token”);
var tokens=new List“在调用受保护的资源之前始终刷新访问令牌”-这并不总是必要的,而且通过消除对每个请求进行重新身份验证的需要,有点挫败了刷新令牌的一个要点(即,减少身份验证服务器的负担)。TokenClient已过时,你能举一个新方法的例子吗?@JuanPablo现在你可以这样使用var response=wait client.RequestRefreshTokenAsync(新的RefreshTokenRequest{Address=discoveryResponse.TokenEndpoint,ClientId=“mvc”,ClientSecret=“secret”,Scope=“my api”,RefreshToken=RefreshToken})您还可以使用HttpClientvar discoveryResponse=wait client.GetDiscoveryDocumentAsync(“http://localhost:5500");
对于任何想知道如何获取实际刷新令牌的人,当您第一次进行身份验证时,您需要在发出请求时将脱机访问
添加到您的作用域中。执行此操作时,刷新令牌将与访问令牌
、到期令牌
和令牌类型
一起返回。
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<AuthenticationToken>
{
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);