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

有人能解释一下OAuth2的优点是什么,以及为什么我们应该实现它吗?我问这个问题是因为我对此有点困惑——以下是我目前的想法:

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

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

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

此外,正如/r/netsec最近所显示的那样,SSL并不是完全安全的,所以把所有东西都放在TLS/SSL而不是安全的HMAC上的推动让我感到困惑。

OAuth认为这并不是100%的安全,而是要发表并完成它。从提供商的角度来看,这听起来并不太有希望。当草案提到6种不同的流程时,我可以看出它想要达到的目的,但在我的脑海中,它就是不合适。

我想这可能更多的是我在努力理解它的好处和原因,而不是实际上不喜欢它,所以这可能是一种毫无根据的攻击,如果这看起来像一种咆哮,我很抱歉。

103125 次浏览

背景:我已经为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访问都使用一个将过期的令牌进行。谷歌在他们的OAuth 2 api上使用了5分钟的过期时间。

因此,除了刷新令牌之外,OAuth 2简化了客户机、服务器和内容提供者之间的所有通信。刷新令牌的存在只是为了在未加密的情况下访问内容时提供安全性。

两条腿的身份验证

但是,有时服务器只需要控制对自己内容的访问。两腿身份验证允许客户端直接使用服务器对用户进行身份验证。

OAuth 2标准化了一些广泛使用的OAuth 1扩展。我最熟悉的是由Twitter介绍的xAuth。你可以在OAuth 2中看到它是资源所有者密码凭证

从本质上讲,如果您可以信任客户端拥有用户的凭据(用户名和密码),客户端就可以直接与内容提供者交换访问令牌。这使得OAuth在移动应用程序上更有用——使用三脚身份验证,您必须嵌入一个HTTP视图,以便处理内容服务器的授权过程。

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

我刚刚用资源所有者密码凭据实现了OAuth 2的服务器端,从客户端角度来看,获取访问令牌变得很简单:从服务器请求一个访问令牌,将客户端id/secret作为HTTP授权标头传递,并将用户的登录/密码作为表单数据传递。

优点:简单

因此,从实现者的角度来看,我在OAuth 2中看到的主要优势是降低了复杂性。它不需要请求签名过程,这个过程并不难,但确实很繁琐。它极大地减少了充当服务客户端所需的工作,这正是(在现代移动世界中)您最想要最小化痛苦的地方。服务器内容提供者端复杂性的降低使其在数据中心更具可伸缩性。

它还将一些目前广泛使用的OAuth 1.0a扩展(如xAuth)编入标准。

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

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

  1. 关注点分离。
  2. 将身份验证与通常服务于业务的web应用程序分离。

通过这样做,

  1. 您可以实现单点登录的替代方案:如果您有多个应用程序信任一个STS。我的意思是,所有应用程序都使用一个用户名。
  2. 您可以允许您的web应用程序(客户端)访问属于用户而不属于web应用程序(客户端)的资源。
  3. 您可以将身份验证过程委托给您信任的第三方,而不必担心用户真实性验证。

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

OAuth 2.0不是身份验证协议。

在用户访问应用程序的上下文中,身份验证告诉应用程序当前用户是谁以及他们是否存在。完整的身份验证协议可能还会告诉您关于该用户的许多属性,例如唯一标识符、电子邮件地址,以及当应用程序说“早安”时如何称呼它们。

但是,OAuth没有告诉应用程序这些。 OAuth完全没有提到用户,也没有说用户如何证明他们的存在,甚至他们是否还在那里。 就OAuth客户机而言,它请求一个令牌,得到一个令牌,并最终使用该令牌访问某些API。它不知道是谁授权了应用程序,也不知道是否有用户在那里

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

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

在Go中,你可以看到coreos/dex,一个开放id连接身份(OIDC)和OAuth 2.0提供程序与可插连接器。

答案来自这篇文章vonc