IdentityServer 3使用刷新令牌刷新用户

Geo*_*ros 11 asp.net angularjs identityserver3

我们正在尝试以正确的方式设置Identity Server 3.我们认证工作正常,我们设法检索刷新令牌.

客户端应用程序正在使用Angular.

现在当acces_token到期时,对其余api的任何调用都失败了(我们设法让它返回401),但我们想知道如何重新验证用户.

在我们的测试中,任何通过Javascript调用的api调用都失败了(401)但是一旦刷新页面,整个机制就开始了.我们确实看到我们被重定向到身份服务器但它没有显示登录页面,我们显然已经用新的令牌发回客户端应用程序.

我想要做的是刷新访问令牌,而不必强迫用户刷新页面.

我不确定的是谁的责任呢?那是客户端应用程序(网站)还是有角度的应用程序?换句话说,如果应用程序透明地处理Angular,或者当它收到401时应该有角度做某事,在这种情况下,我不太确定信息将如何流回Web应用程序.

任何线索?

附加信息:我们正在使用OpenId Connect

Geo*_*ros 4

我成功了!

正如我在评论中所说,我使用了这篇文章。作者引用了我也在使用的一个非常好的库。

事实:

  1. Identity Server 3 在访问令牌刷新时请求客户端密钥
  2. 人们不应该将refresh_token或client_secret存储在javascript应用程序上,因为它们被认为是不安全的(请参阅文章

所以我选择将refresh_token作为加密的cookie发送给此类(ST BTW找到的,只是找不到链接了,抱歉......)

public static class StringEncryptor
{
    public static string Encrypt(string plaintextValue)
    {
        var plaintextBytes = plaintextValue.Select(c => (byte) c).ToArray();
        var encryptedBytes = MachineKey.Protect(plaintextBytes);
        return Convert.ToBase64String(encryptedBytes);
    }

    public static string Decrypt(string encryptedValue)
    {
        try
        {
            var encryptedBytes = Convert.FromBase64String(encryptedValue);
            var decryptedBytes = MachineKey.Unprotect(encryptedBytes);
            return new string(decryptedBytes.Select(b => (char)b).ToArray());
        }
        catch
        {
            return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

JavaScript 应用程序正在从 cookie 中获取值。然后它会删除 cookie,以避免一遍又一遍地发送该内容,这是毫无意义的。

当access_token失效时,我使用加密的refresh_token向应用服务器发送http请求。那是匿名电话。

服务器联系身份服务器并获取一个新的 access_token,并将其发送回 Javascript。这个很棒的库对所有其他请求进行了排队,因此当我带着新令牌回来时,我可以告诉它继续使用authService.loginConfirmed();.

刷新实际上非常简单,因为您所要做的就是使用TokenClientIdentityServer3 中的。完整方法代码:

    [HttpPost]
    [AllowAnonymous]
    public async Task<JsonResult> RefreshToken(string refreshToken)
    {
        var tokenClient = new TokenClient(IdentityServerConstants.IdentityServerUrl + "/connect/token", "my-application-id", "my-application-secret");
        var response = await tokenClient.RequestRefreshTokenAsync(StringEncryptor.Decrypt(refreshToken));

        return Json(new {response.AccessToken});
    }
Run Code Online (Sandbox Code Playgroud)

欢迎评论,这可能是最好的方法。

  • 如果您加密刷新令牌,然后在刷新端点中解密它,这比直接发送刷新令牌更安全吗?如果有人要访问加密的刷新令牌,他们所要做的就是将其发送到您的端点进行解密。问题解决了。这并不比仅按原样发送刷新令牌更安全。如果您担心将刷新令牌暴露给客户端应用程序,您应该将其保留在服务器端并使用某种密钥(身份验证令牌、用户 ID 等)来检索服务器端,然后将其发送到端点。 (6认同)