c# - 如何在 IdentityServer 4 中使用 'refresh_token'?

标签 c# identityserver4

我在 IdentityServer 4 中使用 .net 核心。我有一个 Web api 和一个访问 api 上的安全端点的 MVC 应用程序。它的设置与 IdentityServer 快速入门非常相似:

https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/6_AspNetIdentity

我发现我的 access_tokens 即将到期,我想了解如何重新协商 refresh_tokens

以下面的代码为例(取自快速入门here):

public async Task<IActionResult> 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 中将其设置为 true。请注意,这对隐式/客户端凭据流起作用。

  • 总是在调用 protected 资源之前刷新 access_token
  • 检查当前 access_token 是否即将过期,方法是检查其生命周期并使用 refresh_token 请求新的 access_token(个人偏好)
  • 等待 API 返回 401 并使用 refresh_token 请求新的 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<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);

取自并稍作修改:Source

关于c# - 如何在 IdentityServer 4 中使用 'refresh_token'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44175115/

相关文章:

c# - 如何在 SQL 中组合名字和姓氏并使用 LIKE 进行搜索

C# 在多个后台工作人员完成后更新 UI

c# - 检查字符串是否以列表中的任何字符开头

javascript - mvc .net 表单提交复选框标签在 Internet Explorer 中不起作用

.net-core - Identity Server 4登录后重定向仅在Chrome中不起作用

wpf - 与 WPF 连接的身份服务器

c# - 在单独的线程中启动 WPF 窗口

c# - 使用不同域中的 oidc-client 和 identityServer4 登录

c# - 将自定义参数传递给登录页面 Identity Server 4 中使用的 returnUrl

c# - IdentityServer4 与 EF6