OAUTH2 刷新令牌

Posted

技术标签:

【中文标题】OAUTH2 刷新令牌【英文标题】:OAUTH2 Refresh Token 【发布时间】:2017-04-20 23:28:00 【问题描述】:

我对 OAuth2 中的刷新令牌有点困惑。 就像它说的访问令牌限制了黑客可以使用用户凭据的 1 小时时间窗口,并且刷新令牌是可用于重新创建访问令牌的长效令牌。

如果有人从 cookie 中窃取了访问令牌,我会感到困惑,他也可以窃取刷新令牌,并且可以使用刷新令牌来创建新的访问令牌,因为我在 JQuery(客户端)中有 ajax 请求

注意:我已经创建了 ajax 请求以在服务器端发送刷新令牌,我在此处附加了客户端 ID 和机密以及授权类型刷新令牌。

我已在 cookie 中保存了访问令牌和刷新令牌,并使用以下 ajax 请求获取新的访问令牌

jQuery(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) 

        //console.log('event');console.log(event);
        //console.log('jqXHR');console.log(jqXHR);
        //console.log('ajaxSettings');console.log(ajaxSettings);
        //console.log('thrownError');console.log(thrownError);

        if(jqXHR.status == 403)
        
            console.log('User is not Loged in Redictet to Login Page');
           

        if(jqXHR.status == 401)
        
            var refresh_token = Cookies.get('refresh_token');
            if(refresh_token != undefined)
            
                $.ajax(
                        url: CONNECT_API_URL+'/refresh-token',
                        type: "POST",
                        data: refresh_token: refresh_token ,
                        success: function(response, status, jqXHR)
                            if(response.access_token != undefined)
                            
                                var expires_in = new Date(new Date().getTime() + response.expires_in * 1000);
                var access_token = response.token_type+' '+response.access_token;
                Cookies.set('access_token', access_token,  expires: expires_in );
                Cookies.set('refresh_token', response.refresh_token,  expires: 14 );
                                $.ajax(ajaxSettings); // Re send same ajax request with access token in cookie has been set
                            
                            else
                            
                                console.log('Redirect to login page.');
                            
                        , 
                 );    
            
           


);

我应该如何使用刷新令牌来增强安全性?

【问题讨论】:

您能否告知您在应用程序中使用了哪个 Oauth2 授权流程?另外,是否提到这是单页应用程序或服务器端渲染或移动应用程序? 注意 OAuth2 必须与 SSL/TLS (HTTPS) 一起使用来加密从客户端到服务器的通信通道。 实际上这是使用 REST API 服务的 Web 应用程序,我正在使用 OAuth2 grant_type 密码。 @ViníciusFagundes 即使它是 HTTPS,但我认为可能存在一些 XSS,因此攻击者可以获得 cookie 刷新令牌和访问令牌,在这种情况下,刷新令牌如何帮助提高安全性 @vaya 我已经创建了 REST 服务,它从用户那里获取用户名密码,在服务器端我将 ClientId 和密码附加到密码授予类型 【参考方案1】:

在这篇标题为 Refresh Tokens: When to Use Them and How They Interact with JWTs 的博客文章中,您的问题得到了很好的讨论。

引用那篇文章:

刷新令牌通常受到严格的存储要求,以确保它们不会泄露。

在RFC6819 spec 中,他们写了以下关于在客户端上存储访问令牌的内容:

5.1.6。访问令牌

应使用以下措施来保护访问令牌:

将它们保存在临时内存中(客户端可访问 仅限应用程序)。 使用安全传输 (TLS) 安全地传递令牌。 确保客户端应用程序不与 3rd 共享令牌 派对。

关于刷新令牌的发行:

5.2.2.1。刷新令牌的限制发行

授权服务器可以根据适当的策略决定, 不要发出刷新令牌。由于刷新令牌是长期的 凭据,它们可能会被盗。例如,如果 授权服务器不信任客户端安全地存储此类 令牌,它可能会拒绝向这样的客户端颁发刷新令牌。

这意味着您可能应该仔细考虑要存储刷新令牌的位置。这篇Where to Store your JWTs – Cookies vs HTML5 Web Storage 的帖子正是针对这个主题。

同样提到in this answer on ***,只有refresh_token 不足以获得新的access_token

刷新令牌如果被泄露,将毫无用处,因为攻击者除了刷新令牌之外还需要客户端 ID 和密码才能获得访问令牌。

这也可以在同一个RFC6819 spec中找到:

5.2.2.2。 Refresh Token 绑定到“client_id”

授权服务器应将每个刷新令牌与 发给它的客户的标识符。授权 服务器应检查是否存在相同的“client_id” 请求刷新访问令牌。如果可能(例如,机密 客户端),授权服务器应验证相应的 客户。

这是针对刷新令牌被盗或泄漏的对策。

刷新令牌只能使用一次。当使用refresh_token 时,它将返回一个新的access_token 和一个新的refresh_token。它使旧的refresh_token 变得无用,这意味着它不能再使用了。

它还允许身份验证服务器识别refresh_token 已被泄露,因为它只能使用一次。如果具有相同refresh_token 的新更新请求进入身份验证服务器,则知道发生了一些可疑的事情。不确定服务器处理这种情况的正确方法是什么......(也许其他人可以对此有所了解)

这也在RFC6819 spec:

5.2.2.3。刷新令牌轮换

刷新令牌轮换旨在自动检测和 防止尝试并行使用相同的刷新令牌 不同的应用程序/设备。如果令牌从 客户端,随后被攻击者和攻击者使用 合法的客户。基本思路是改变刷新令牌 每个刷新请求的值,以检测尝试 使用旧的刷新令牌获取访问令牌。由于 授权服务器无法确定是攻击者还是 合法客户端正在尝试访问,以防此类访问 尝试有效的刷新令牌和访问授权 与之关联的都被撤销。

OAuth 规范支持此措施,因为令牌的 response 允许授权服务器返回一个新的刷新 即使对于授权类型为“refresh_token”的请求,也可以使用令牌。

注意:此措施可能会在集群环境中引起问题, 因为必须确保使用当前有效的刷新令牌。在 在这样的环境下,其他措施可能更合适。

您的访问和刷新令牌可能会在客户端上被泄露,但令牌也可能在您的客户端和服务器之间的某个地方被截获。 refresh_token 只发送一次给客户端,而access_token 每次请求都会发送到服务器,这就是为什么中间人得到你的access_token 的机会很大比你的refresh_token 被入侵的机会更大。

一般来说,完全理解 OAuth2 协议是很好的,这样您就可以正确地实现它。关于安全性,我会简单地说:

使用 JWT 的首要要求是在客户端和服务器之间正确配置 https 连接,以便所有令牌在来回发送时都得到正确加密。 第二个要求是您以安全的方式将令牌存储在客户端上。

我希望这能让您对这个主题有所了解。如果有人想添加或更正我的帖子,请随时编辑/更新/赞美答案或发表评论。

【讨论】:

以上是关于OAUTH2 刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章

了解 Google OAuth2 刷新令牌

刷新 OAuth2 访问令牌的正确范例

如何基于使用 Oauth2 协议的身份验证改进 JWT 访问令牌和刷新令牌?

Spring OAuth2刷新令牌刷新访问令牌后更改

如何获得一个无限期使用的访问令牌/刷新令牌(oauth2 - Spotify API)

撤销 JWT Oauth2 刷新令牌