OAuth 2如何使用安全性令牌防范诸如重播攻击之类的事情?


564

据我了解,OAuth 2中发生了以下一系列事件,以便Site-A从中访问用户的信息Site-B

  1. Site-A在上注册Site-B,并获取密钥和ID。
  2. 用户告诉Site-A访问Site-B用户发送给Site-B他们讲Site-B,他们的确会想给Site-A权限的具体信息。
  3. Site-B用户Site-A以及授权码重定向回。
  4. Site-A然后将该授权码及其秘密传递回以Site-B换取安全令牌。
  5. Site-A然后将安全令牌与请求捆绑在一起Site-B,代表用户发出请求。

从安全性和加密的角度来看,所有这些工作如何运作?OAuth 2如何使用安全性令牌防范诸如重播攻击之类的事情?


49
oauth2在这里简单地解释了:gist.github.com/mziwisky/10079157
Paolo

4
阅读规范:tools.ietf.org/html/rfc6749您可能会惊讶于它的可理解性。可能还不错,这也是正确的。
Kris Vandermotten 2014年

1
这个问题及其(当前的)答案都集中在OAuth 2.0中一种特定的“授予类型”(即code)上,但是OAuth 2.0中定义了其他与不同用例相关的授予类型(例如,与用户无关的授予类型)。
Hans Z. 2014年

4
哦,为什么不使用“ IdProvider Site”等可读性更高的内容替换“ Site B”?
尤里(Yurii)2015年

Answers:


1378

OAuth 2.0在现实生活中的工作方式:

当我上班的时候,我在车道上开车去看Olaf的面包店时,看到窗户上最美味的甜甜圈-我的意思是,那东西滴满了巧克力般的美味。所以我走进去,要求“我必须吃那个甜甜圈!”。他说,“确定将是30美元。”

是的,我知道,一个甜甜圈要30美元!一定很好吃!我突然拿起钱包,突然听到厨师大喊“不!不给你甜甜圈”。我问:为什么?他说他只接受银行转帐。

认真吗 是的,他是认真的。我差点就走到那儿,但是甜甜圈呼唤我:“吃了,我很好吃……”。我要服从甜甜圈的命令是谁?我说了可以。

他递给我一张便条,上面写着他的名字(厨师,不是甜甜圈):“告诉他们奥拉夫给你发来的信”。他的名字已经在笔记中了,所以我不知道那是什么意思,但是还可以。

我开车去了一个半小时。我把纸条交给了出纳员。我告诉她奥拉夫送我了。她给了我其中一种表情,说:“我会读”。

她记下我的钞票,问我的身份证,问我可以给他多少钱。我告诉她30美元。她做了些涂鸦,并递给我另一张纸条。这上面有很多数字,我想这就是他们记录笔记的方式。

那时候我饿了。我冲出那里,一个半小时后,我回来了,站在奥拉夫的面前,张开了我的纸条。他拿着它,看了一眼,说:“我会回来的”。

我以为他要吃甜甜圈了,但是30分钟后我开始变得可疑了。所以我问柜台后面的那个人:“奥拉夫在哪里?”。他说:“他去赚钱”。“你什么意思?”。“他记钱到银行”。

呵呵...奥拉夫(Olaf)注意到银行给了我,然后又回到银行从我的帐户中取钱。既然他有了银行给我的钞票,银行就知道他是我在说的那个人,而且因为我和银行谈话,他们知道只给他30美元。

我一定花了很长时间才弄清楚,因为当我抬起头来时,奥拉夫站在我面前终于把甜甜圈递给我。在我离开之前,我不得不问:“奥拉夫,你总是这样卖甜甜圈吗?”。“不,我曾经做过不同的事情。”

嗯 当我回到车上时,手机响了。我没有理会,可能是我的工作要求开除我,我的老板真是个***。此外,我还想着刚刚经历的过程。

我的意思是考虑一下:我能够让Olaf从我的银行帐户中取出30美元,而不必向他提供我的帐户信息。而且我不必担心他会掏出太多钱,因为我已经告诉银行只允许他收取30美元。银行知道他是正确的人,因为他得到了他们给我的给奥拉夫的钞票。

好吧,确定我会从口袋里递给他30美元。但是既然他有了那张纸条,我就可以告诉银行让他每周拿走30美元,然后我就可以在面包店露面,而不必再去银行了。如果愿意,我什至可以通过电话订购甜甜圈。

当然,我永远不会那样做-甜甜圈真令人恶心。

我想知道这种方法是否具有更广泛的应用。他提到这是他的第二种方法,我可以称其为Olaf 2.0。无论如何,我最好回到家,我必须开始寻找新工作。但是,在我从整个城市的新地方买到一种草莓奶昔之前,我需要一些东西来冲走那种甜甜圈的味道。


41
好吧,实际上,即使您不订购任何甜甜圈,奥拉夫也应该能够从他的帐户中随时支取30美元。有趣的是,这是真正的oauth2.0方案的主要目标:)这当然是一个不错的答案,但是无论您是谁,请浏览Paolo在对该问题的评论中提到的git gist(gist.github.com/mziwisky/ 10079157)。很好的补充读物可以使概念更清晰。
萨米龙

4
不错的答案,但有2个要提高的要点:1.正如@Samiron所指出的,Olaf可以随时取30美元。2.在真实的OAuth2.0场景中,Olaf在将钱从银行提取出来之前将无法为甜甜圈服务。在此示例中,他本可以保留支票,而只是将他来之不易的甜甜圈交给路易斯。因此,如果我们更改示例以使我授权Olaf从我认识的第三方那里获取面团,那么这将更有意义,因为Olaf在开始烘烤甜甜圈之前必须先获得面团(假设孤独的甜甜圈Olaf只是出于展示目的!)。
Ticker23 '17

4
ticker23,不幸的是,甜甜圈的故事胜过了您的技术修正-当我阅读该故事时,我就被卖了。它是由荷马·辛普森(Homer Simpson)撰写的。
shevy

4
@Prageeth Olaf始终将钞票放在一个安全的盒子中来回存放,如果被篡改,该盒子会泄漏墨水,这将需要很多时间才能恢复它。银行还会在第一次访问时带上客户指纹,如果Olaf在烘烤事故中失去手指,那么他将不得不要求Luis重新设置银行转帐,并且下次银行必须通过他的Breaking Bread纹身识别Olaf 。
克里斯(Chris)

11
我喜欢下一个人一样喜欢可爱的答案,当他们的可爱可以使答案更容易获得时,真是太棒了……但是,总而言之,Stack Overflow的目的是教育人们,但是这个可爱的故事并没有做到这一点。为了甚至理解甜甜圈的类比,您必须已经了解OAuth2的工作原理,但是答案的重点应该是准确地解释这一点。请考虑编辑此(顶部)答案以实际解释概念,而不仅仅是在结尾时倾斜地引用它们,即使这样做要花一两个笑话。
machineghost

133

根据我所读的内容,这就是全部的工作方式:

问题中概述的一般流程是正确的。在步骤2中,对用户X进行身份验证,并且还授权站点A访问站点B上用户X的信息。在步骤4中,站点将其秘密传递回站点B,以对其进行身份验证以及授权码,从而指示出它要求(用户X的访问令牌)。

总体而言,OAuth 2实际上是一个非常简单的安全模型,并且加密从未直接发挥作用。相反,Secret和Security Token实质上都是密码,整个事情仅由https连接的安全性来保护。

OAuth 2没有针对安全令牌或密钥的重放攻击的保护措施。取而代之的是,它完全依赖于站点B对这些项目负责,而不是让它们离开,并且在传输过程中通过https发送它们(https将保护URL参数)。

授权代码步骤的目的仅仅是为了方便,并且授权代码本身并不特别敏感。当向站点B询问用户X的访问令牌时,它为站点A的用户X的访问令牌提供了通用标识符。站点B上仅用户X的用户ID将无法正常工作,因为可能有许多未完成的访问令牌等待同时分发给其他站点。


28
您忽略了授权代码的重要功能。为什么不立即返回刷新令牌(您称为安全令牌),而不是为此而花费额外的步骤来交换授权代码呢?因为捕获刷新令牌将允许重放攻击,而授权代码只能使用一次。
2011年

3
好的,@ mauricen,这是有道理的。。。。。。。。。。
MIKKEL先生

15
授权代码是通过用户传递的,因此(例如)可以存储为cookie(请参阅stackoverflow.com/questions/4065657/…)。刷新令牌直接在两个站点之间传递,因此脆弱性要小得多。
莫里斯·纳夫塔琳

出于好奇,OAuth是否会返回任何唯一标识符供程序使用?例如,我当前依赖于MAC地址来进行用户标识,但是这样说,MAC是不可靠的/容易被欺骗的等。如果确实允许我唯一地标识用户,我可能只是放弃MAC地址标识机制并使用OAuth。
theGreenCabbage 2014年

1
注意在此图中:tools.ietf.org/html/rfc6749#section-4.1未显示“机密”,仅显示了客户端标识符(问题中的ID)。为什么秘密很重要,为什么它不包含在RFC中?同样在问题中,还建议在客户端ID(A)的初始传输中传递本地状态,并重定向回客户端以及授权码以防止XSSF。
David Williams

104

OAuth是一种协议,三方应用可以使用该协议访问您存储在另一个网站中的数据,而无需使用您的帐户和密码。有关更正式的定义,请参阅Wiki或规范。

这是一个用例演示:

  1. 我登录到LinkedIn,并希望与我的Gmail联系人中的一些朋友建立联系。LinkedIn支持这一点。它将从gmail请求安全资源(我的gmail联系人列表)。所以我点击这个按钮:
    添加连接

  2. 输入我的帐户和密码后,将弹出一个网页,并显示Gmail登录页面:
    添加连接

  3. 然后,Gmail会显示一个同意页面,我单击“接受”: 添加连接

  4. 现在,LinkedIn可以在Gmail中访问我的联系人: 添加连接

下面是上面示例的流程图:

添加连接

步骤1:LinkedIn向Gmail的授权服务器请求令牌。

步骤2:Gmail授权服务器对资源所有者进行身份验证,并向用户显示同意页面。(如果用户尚未登录,则需要登录到Gmail)

步骤3:用户向LinkedIn授予访问Gmail数据的请求。

步骤4:Gmail授权服务器以访问令牌作为响应。

步骤5:LinkedIn使用此访问令牌调用Gmail API。

步骤6:如果访问令牌有效,则Gmail资源服务器将返回您的联系人。(令牌将由Gmail资源服务器验证)

您可以在此处从有关OAuth的详细信息中获取更多信息。


您所有的图像都丢失了。您有机会将它们加载到stack.imgur吗?
克里斯·

1
这怎么可能是正确的?这个过程不是由坐在浏览器前的用户(而不是LinkedIn)发起的。但是您将其作为步骤3。这是我没有得到的。
马特

17
最简单的解释。谢谢,我再也不会买甜甜圈了
OverCoder

第四步linkedin返回授权令牌。这必须在第5步中提供,在该步骤中,我们将获得访问令牌和刷新令牌,这些令牌可进一步用于受保护的资源。
amesh

@amesh谢谢,你说得对,这就是授权码流,在这里我简单的方式展现的OAuth 2的基本思路刚才所说
欧文曹

24

图1,摘自RFC6750

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

13

这就是Oauth 2.0的工作方式,本文对此进行了详细说明

在此处输入图片说明


您可以通过不使用Facebook或其他第三方来描述OAUTH2,但是如果您将秘密密钥和TOTP令牌与电话应用程序一起使用来保护Web应用程序,则可以描述OAUTH2吗?
格兰特

在此示例中,Facebook是授权服务器,它向任何客户端颁发访问令牌,以便他们可以访问Facebook API。如果要保护API,则需要实现自己的授权服务器。然后,确定要用于获取访问令牌的Grant类型。告诉我你到底想要什么?会解释。
Suraj

我正在考虑使用springboot安全性进行设置。客户端(电话)和Webapp在注册时交换机密-然后使用Google身份验证器生成基于时间/秘密的代码,以便在登录时输入密码和密码。
艾尔·格兰特

我的最后一句话给您带来启发了吗?看到我的微博信息的个人资料
铝格兰特

您可以在注册时获取客户ID和密码。然后,用客户端ID向您的webapp(授权服务器)发出登录请求。Web应用程序验证客户端ID,然后将OTP发送到电话。Phone向客户端发出另一个带有客户端机密的请求,以请求Webapp与访问令牌交换OTP。手机使用此accss令牌访问Webapp上受保护的资源。我认为这将是给定方案的Oauth2流。让我知道是否有帮助。
Suraj

10

这是一颗宝石:

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

非常简短的摘要:

OAuth定义了四个角色:

  1. 资源所有者
  2. 客户
  3. 资源服务器
  4. 授权服务器

您(资源所有者)拥有一部手机。您有多个不同的电子邮件帐户,但是您希望所有电子邮件帐户都在一个应用程序中,因此您无需继续切换。因此,您的GMail(客户端)要求(通过Yahoo的授权服务器)访问Yahoo电子邮件(资源服务器),以便您可以在GMail应用程序中阅读这两封电子邮件。

OAuth存在的原因是因为GMail存储您的Yahoo用户名和密码是不安全的。

在此处输入图片说明


8

另一个答案非常详细,可以解决OP提出的大部分问题。

为了详细说明,特别是要解决OP的问题“ OAuth 2如何使用安全性令牌来防止诸如重放攻击之类的事情?”,在官方建议中还提供了另外两种保护措施,以实现 OAuth 2:

1)令牌通常具有较短的有效期(http://tools.ietf.org/html/rfc6819#section-5.1.5.3):

令牌的有效时间短是一种防范以下威胁的方法:

  • 重播...

2)当站点A使用令牌时,建议不要将其作为URL参数显示,而是在授权请求标头字段(http://tools.ietf.org/html/rfc6750)中显示:

客户端应该使用带有“ Bearer” HTTP授权方案的“ Authorization”请求标头字段,通过承载令牌发出经过身份验证的请求。...

除非在参与的浏览器无法访问“授权”请求标头字段的应用程序上下文中,否则不应使用“ application / x-www-form-urlencoded”方法。...

包含URI查询参数...以记录当前使用情况;由于其安全性缺陷,不建议使用


3

这可能是OAuth2如何适用于所有4种授权类型(即应用可以获取访问令牌的4种不同流)的最简单解释。

相似

所有授权类型流程都包含两个部分:

  • 获取访问令牌
  • 使用访问令牌

第二部分“使用访问令牌”对于所有流都是相同的

区别

每种授予类型的流程“获取访问令牌”的第一部分有所不同。

但是,通常,“获取访问令牌”部分可以归纳为5个步骤:

  1. 向OAuth提供者(例如Twitter等)预先注册您的应用(客户端),以获取客户端ID /秘密
  2. 在页面上创建具有客户端ID和所需范围/权限的社交登录按钮,以便在单击的用户重定向到OAuth提供程序进行身份验证时
  3. OAuth提供者请求用户向您的应用(客户端)授予权限
  4. OAuth提供者发出代码
  5. 应用程序(客户端)获取访问令牌

这是一个并排图,比较了基于5个步骤的每种授权类型流程的不同。

此图来自https://blog.oauth.io/introduction-oauth2-flow-diagrams/

在此处输入图片说明

每个都有不同级别的实现难度,安全性和用例。根据您的需求和情况,您将不得不使用其中之一。使用哪个?

客户凭证:如果您的应用仅服务于单个用户

资源所有者密码凭证:仅当用户必须将其凭据移交给应用程序时,才应将其用作最后手段,这意味着应用程序可以执行用户可以做的所有事情

授权码:获得用户授权的最佳方法

隐式:如果您的应用是移动应用还是单页应用

这里有更多关于此选择的说明:https : //blog.oauth.io/choose-oauth2-flow-grant-types-for-app/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.