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

时间:2015-12-10 13:23:22

标签: asp.net angularjs identityserver3

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

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

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

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

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

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

有任何线索吗?

其他信息:我们正在使用OpenId Connect

2 个答案:

答案 0 :(得分:4)

我开始工作了!

正如我在评论中所说,我使用this文章。作者正在引用我正在使用的very nice lib

事实:

  1. Identity Server 3在访问令牌刷新时请求客户端密钥
  2. 不应该在javascript应用程序中存储refresh_token或client_secret,因为它们被认为是不安全的(请参阅the article
  3. 所以我选择发送refresh_token作为en加密的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;
            }
        }
    }
    

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

    当access_token变为无效时,我使用加密的refresh_token向应用服务器发送http请求。这是一个匿名电话。

    服务器联系身份服务器并获取一个发送回Javascript的新access_token。 awesome library将所有其他请求排队,所以当我回复新令牌时,我可以告诉它继续使用authService.loginConfirmed();

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

        [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});
        }
    

    欢迎提出意见,这可能是最好的方法。

答案 1 :(得分:1)

供将来参考 - 在角度(或其他JS)应用程序中使用刷新令牌不正确,因为刷新令牌太敏感而无法存储在浏览器中。您应该使用基于identityserver cookie的静默续订来获取新的访问令牌。另请参阅oidc-client-js javascript库,因为这可以为您管理无声续订。