OAuth 2.0:好处和用例-为什么?


256

谁能解释OAuth2有什么好处,为什么我们要实现它?我问是因为对此有些困惑-这是我目前的想法:

OAuth1(更确切地说是HMAC)请求看起来合乎逻辑,易于理解,易于开发并且非常安全。

相反,OAuth2带来了授权请求,访问令牌和刷新令牌,并且您必须在会话开始时发出3个请求才能获取所需的数据。即使这样,当令牌过期时,您的请求之一最终也会失败。

为了获得另一个访问令牌,您可以使用与访问令牌同时传递的刷新令牌。从安全角度来看,这会使访问令牌无效吗?

另外,正如/ r / netsec最近显示的那样,SSL并不是完全安全的,因此将所有内容都放到TLS / SSL而不是安全的HMAC的推动使我感到困惑。

OAuth争辩说这不是100%的安全性,而是使其发布和完成。从提供商的角度来看,这听起来并不乐观。当提到6种不同的流程时,我可以看到该草案试图达到的目的,但是我的脑袋并没有完全融合在一起。

我认为与实际不喜欢它相比,了解它的好处和推理可能要比我更努力,因此这可能是不必要的攻击,如果这看起来像是咆哮,那就对不起。


Answers:


324

背景:我已经为OAuth 1.0a和2.0编写了客户端和服务器堆栈。

OAuth 1.0a和2.0都支持两足式身份验证三足式身份验证,在这种情况下,服务器可以确保用户的身份。(其中由内容提供商确保用户身份)。三足身份验证是授权请求和访问令牌起作用的地方,需要注意的是OAuth 1也具有这些身份。

复杂的一:三足身份验证

OAuth规范的主要目的是让内容提供者(例如Facebook,Twitter等)确保服务器(例如希望代表客户端与内容提供者对话的Web应用)客户端具有某种身份。三足式身份验证提供的功能是无需客户端或服务器就无需知道该身份的详细信息(例如,用户名和密码)的能力。

无需(?)深入了解OAuth的细节:

  1. 客户端向服务器提交授权请求,以确认客户端是其服务的合法客户端。
  2. 服务器将客户端重定向到内容提供者,以请求对其资源的访问。
  3. 内容提供者会验证用户的身份,并经常请求其访问资源的许可。
  4. 内容提供商将客户端重定向回服务器,通知其成功或失败。该请求包括成功的授权码。
  5. 服务器向内容提供者发出带外请求,并交换访问令牌的授权代码。

服务器现在可以通过传递访问令牌代表用户向内容提供者发出请求。

每个交换(客户端->服务器,服务器->内容提供程序)都包含对共享机密的验证,但是由于OAuth 1可以在未加密的连接上运行,因此每个验证都无法通过网络传递机密。

正如您所指出的,HMAC已经完成。客户端使用它与服务器共享的机密来为其授权请求签名自变量。服务器接受参数,并使用客户端的密钥对其进行签名,并能够查看其是否为合法客户端(在上面的步骤1中)。

此签名需要客户端和服务器双方就参数的顺序达成一致(因此,他们要对完全相同的字符串进行签名),而有关OAuth 1的主要抱怨之一是,它要求服务器和客户端都进行排序和签名相同。这是很奇怪的代码,或者是正确的代码,或者您得到的401 Unauthorized帮助很少。这增加了编写客户端的障碍。

通过要求授权请求在SSL上运行,OAuth 2.0完全不需要参数排序和签名。客户端将其秘密传递给服务器,服务器直接对其进行验证。

服务器->内容提供程序连接中存在相同的要求,并且由于SSL消除了编写访问OAuth服务的服务器的障碍。

这使上面的步骤1、2和5变得容易得多。

因此,在这一点上,我们的服务器具有一个永久访问令牌,该令牌是用户的用户名/密码。通过将访问令牌作为请求的一部分传递(作为查询参数,HTTP标头或POST表单数据),它可以代表用户向内容提供者发出请求。

如果仅通过SSL访问内容服务,那么我们就完成了。如果可以通过纯HTTP使用,则我们希望以某种方式保护该永久访问令牌。嗅探该连接的任何人都将永远能够访问该用户的内容。

OAuth 2解决的方法是使用刷新令牌。刷新令牌将成为等效的永久密码,并且仅通过SSL传输。当服务器需要访问内容服务时,它将刷新令牌交换为短暂的访问令牌。这样,所有可嗅探的HTTP访问都是使用将过期的令牌进行的。Google的OAuth 2 API使用的有效期为5分钟。

因此,除了刷新令牌之外,OAuth 2还简化了客户端,服务器和内容提供商之间的所有通信。并且仅当未加密访问内容时,刷新令牌才存在以提供安全性。

两足式身份验证

但是,有时服务器仅需要控制对其自身内容的访问。两足式身份验证允许客户端直接通过服务器对用户进行身份验证。

OAuth 2标准化了对OAuth 1的一些扩展,这些扩展已得到广泛使用。我最了解的一个是Twitter引入的xAuth。您可以在OAuth 2中将其视为“ 资源所有者密码凭据”

本质上,如果您可以使用用户的凭据(用户名和密码)信任客户端,则他们可以直接与内容提供者交换这些凭据以获得访问令牌。这使OAuth在移动应用程序上更加有用-使用三足身份验证,您必须嵌入HTTP视图才能处理内容服务器的授权过程。

对于OAuth 1,这不是官方标准的一部分,并且需要与所有其他请求相同的签名过程。

我刚刚使用资源所有者密码凭证实现了OAuth 2的服务器端,从客户端的角度来看,获取访问令牌非常简单:从服务器请求访问令牌,将客户端ID /秘密作为HTTP授权标头传递,用户的登录名/密码作为表单数据。

优势:简单

因此,从实现者的角度来看,我在OAuth 2中看到的主要优点是降低了复杂性。它不需要请求签名过程,这不是很困难,但是肯定很麻烦。它极大地减少了充当服务客户所需的工作,而这正是您(最现代的移动世界)最希望减轻痛苦的地方。服务器->内容提供商端的复杂性降低,使其在数据中心中更具可伸缩性。

并且它把现在广泛使用的OAuth 1.0a扩展(例如xAuth)编入标准。


20
关于术语:最好使用受影响各方的正式名称(授权服务器,资源服务器,资源所有者),而不使用不清楚的名称(客户端,服务器,用户..)。
艾登K.

嗨,彼得,您能用授权服务器,资源服务器,资源所有者..代表客户,服务器,用户..像Aydin K所说的那样更改帖子。它主要对新手有帮助。谢谢。
JustCode

@Aydin K您可以评论比较授权服务器,资源服务器,代表客户端,服务器,用户的资源所有者。因为我也是Aouth的新成员。
JustCode '17

如果有人不了解oauth。用oauth术语而不是简单的英语解释oauth似乎没有效果。
雅各布

7

首先,如OAuth身份验证中明确指出的

OAuth 2.0不是身份验证协议。

用户访问应用程序时的身份验证告诉应用程序当前用户是谁以及他们是否存在。完整的身份验证协议可能还会告诉您有关此用户的许多属性,例如唯一标识符,电子邮件地址,以及在应用程序显示“ Good Morning”时调用该对象的方式。

但是,OAuth不会告诉应用程序。OAuth绝对不会对用户说任何话,也不会说用户如何证明他们的存在或者即使他们仍然在场。就OAuth客户端而言,它要求一个令牌,获得一个令牌,并最终使用该令牌访问某些API。它对谁授权该应用程序,甚至根本没有用户一无所知。

有一个使用OAuth进行用户身份验证的标准:OpenID Connect,与OAuth2兼容。

OpenID Connect ID令牌是签名的JSON Web令牌(JWT),它与常规OAuth访问令牌一起提供给客户端应用程序。ID令牌包含一组有关身份验证会话的声明,包括用户的标识符(子),发布令牌的身份提供者的标识符(iss)以及为其创建令牌的客户端的标识符(音频)。

在Go中,您可以查看coreos / dex,OpenID Connect身份(OIDC)和带有可插拔连接器的OAuth 2.0提供程序。

从这个帖子答案vonc


因此,如果您要构建的应用程序中除了您自己的客户端之外没有其他客户端,那么实施OAuth还是明智的选择?还是坚持直接使用HTTP基本身份验证,从而完全避免OAuth更好?
CristianHG

3

我对这个问题的回答会稍有不同,我会非常准确和简短,主要是因为@Peter T回答了所有问题。

我从该标准中看到的主要收获是尊重两个原则:

  1. 关注点分离。
  2. 从通常为业务服务的Web应用程序中分离身份验证。

通过这样做,

  1. 您可以实现“单点登录”的替代方法:如果您有多个应用程序信任一个STS。我的意思是,所有应用程序都有一个用户名。
  2. 您可以使您的Web应用程序(客户端)能够访问属于用户而不属于Web应用程序(客户端)的资源。
  3. 您可以将身份验证过程委托给您信任的第三方,而不必担心用户真实性验证。
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.