ChatGPT解决这个技术问题 Extra ChatGPT

OAuth 2.0:优势和用例——为什么?

谁能解释 OAuth2 的优点以及我们为什么要实施它?我问是因为我对此有点困惑——这是我目前的想法:

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

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

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

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

OAuth 认为这不是 100% 安全,而是发布和完成它。从提供商的角度来看,这听起来并不乐观。当草案提到 6 种不同的流程时,我可以看到草案试图实现的目标,但它在我的脑海中并不适合。

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


C
Community

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

OAuth 1.0a 和 2.0 都支持双腿身份验证,其中向服务器保证用户的身份,以及三腿身份验证,其中服务器由用户身份的内容提供者保证。三足身份验证是授权请求和访问令牌发挥作用的地方,重要的是要注意 OAuth 1 也有这些。

复杂一:三足认证

OAuth 规范的一个要点是内容提供者(例如 Facebook、Twitter 等)向服务器(例如希望代表客户端与内容提供者对话的 Web 应用程序)保证客户端具有某种身份.三足身份验证提供的功能是无需客户端或服务器知道该身份的详细信息(例如用户名和密码)就可以做到这一点。

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

客户端向服务器提交授权请求,服务器验证客户端是其服务的合法客户端。服务器将客户端重定向到内容提供者以请求访问其资源。内容提供者验证用户的身份,并经常请求他们访问资源的权限。内容提供者将客户端重定向回服务器,通知它成功或失败。此请求包括成功的授权代码。服务器向内容提供者发出带外请求,并用授权码交换访问令牌。

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

每个交换(客户端->服务器,服务器->内容提供者)都包括对共享密钥的验证,但是由于 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 中将其视为 Resource Owner Password Credentials

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

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

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

优点:简单

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

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


关于术语:最好坚持受影响方的正式名称(授权服务器、资源服务器、资源所有者),而不是使用不清楚的名称(客户端、服务器、用户 ..)。
如果有人不懂oauth。使用 oauth 术语而不是简单的英语来解释 oauth 似乎并不高效。
r
radhakrishnan

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

OAuth 2.0 不是身份验证协议。

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

但是,OAuth 不会告诉应用程序这些。 OAuth 完全没有说明用户,也没有说明用户如何证明他们的存在,或者即使他们仍然在那里。就 OAuth 客户端而言,它请求令牌,获得令牌,并最终使用该令牌访问某些 API。它不知道谁授权了该应用程序,或者根本不知道那里是否有用户。

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

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

在 Go 中,您可以查看 coreos/dex,一个 OpenID Connect Identity (OIDC) 和 OAuth 2.0 Provider with Pluggable Connector。

这篇文章的回答vonc


那么,如果您正在构建一个除了您自己的客户端之外没有其他客户端的应用程序,那么实施 OAuth 是否是可取的?还是坚持直接 HTTP Basic 身份验证,完全避免 OAuth 会更好吗?
A
Assil

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

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

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

通过这样做,

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