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

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

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

以以下代码为例(取自quickstart 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响应。是否有内置机制可以使用access_token重新协商refresh_token

最佳答案

没有内置系统可以刷新access_token。但是,您可以使用IdentityModel包来请求带有access_token的新refresh_token
Client具有属性AllowOfflineAccess,您应该在IdentityServer中将其设置为true。请注意,对于隐式/客户端凭据流,不起作用,不起作用。

  • 始终在调用 protected 资源
  • 之前刷新access_token
  • 通过检查其生命周期来检查当前access_token是否即将到期,并使用access_token(个人首选项)
  • 请求新的refresh_token
  • 等待API返回401广告,并请求使用access_token
  • 的新refresh_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/

    10-10 21:41