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

发布于 2024-12-06 18:32:40 字数 538 浏览 1 评论 0原文

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

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

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

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

另外,正如 /r/netsec 最近所表明的那样,SSL 并不完全安全,因此将所有内容都转移到 TLS/SSL 而不是安全的 HMAC 上的做法让我感到困惑。

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

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

Could anyone explain what's good about OAuth2 and why we should implement it? I ask because I'm a bit confused about it — here's my current thoughts:

OAuth1 (more precisely HMAC) requests seem logical, easy to understand, easy to develop and really, really secure.

OAuth2, instead, brings authorization requests, access tokens and refresh tokens, and you have to make 3 requests at the very start of a session to get the data you're after. And even then, one of your requests will eventually end up failing when the token expires.

And to get another access token, you use a refresh token that was passed at the same time as the access token. Does that make the access token futile from a security point of view?

Plus, as /r/netsec have showed recently, SSL isn't all entirely secure, so the push to get everything onto TLS/SSL instead of a secure HMAC confuses me.

OAuth are arguing that it's not about 100% safety, but getting it published and finished. That doesn't exactly sound promising from a provider's point of view. I can see what the draft is trying to achieve when it mentions the 6 different flows, but it's just not fitting together in my head.

I think it might be more my struggling to understand it's benefits and reasoning than actually disliking it, so this may be a bit of an unwarranted attack, and sorry if this could seem like a rant.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

束缚m 2024-12-13 18:32:40

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

OAuth 1.0a 和 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)编入标准。

Background: I've written client and server stacks for OAuth 1.0a and 2.0.

Both OAuth 1.0a & 2.0 support two-legged authentication, where a server is assured of a user's identity, and three-legged authentication, where a server is assured by a content provider of the user's identity. Three-legged authentication is where authorization requests and access tokens come into play, and it's important to note that OAuth 1 has those, too.

The complex one: three-legged authentication

A main point of the OAuth specs is for a content provider (e.g. Facebook, Twitter, etc.) to assure a server (e.g. a Web app that wishes to talk to the content provider on behalf of the client) that the client has some identity. What three-legged authentication offers is the ability to do that without the client or server ever needing to know the details of that identity (e.g. username and password).

Without (?) getting too deep into the details of OAuth:

  1. The client submits an authorization request to the server, which validates that the client is a legitimate client of its service.
  2. The server redirects the client to the content provider to request access to its resources.
  3. The content provider validates the user's identity, and often requests their permission to access the resources.
  4. The content provider redirects the client back to the server, notifying it of success or failure. This request includes an authorization code on success.
  5. The server makes an out-of-band request to the content provider and exchanges the authorization code for an access token.

The server can now make requests to the content provider on behalf of the user by passing the access token.

Each exchange (client->server, server->content provider) includes validation of a shared secret, but since OAuth 1 can run over an unencrypted connection, each validation cannot pass the secret over the wire.

That's done, as you've noted, with HMAC. The client uses the secret it shares with the server to sign the arguments for its authorization request. The server takes the arguments, signs them itself with the client's key, and is able to see whether it's a legitimate client (in step 1 above).

This signature requires both the client and the server to agree on the order of the arguments (so they're signing exactly the same string), and one of the main complaints about OAuth 1 is that it requires both the server and clients to sort and sign identically. This is fiddly code and either it's right or you get 401 Unauthorized with little help. This increases the barrier to writing a client.

By requiring the authorization request to run over SSL, OAuth 2.0 removes the need for argument sorting and signing altogether. The client passes its secret to the server, which validates it directly.

The same requirements are present in the server->content provider connection, and since that's SSL that removes one barrier to writing a server that accesses OAuth services.

That makes things a lot easier in steps 1, 2, and 5 above.

So at this point our server has a permanent access token which is a username/password equivalent for the user. It can make requests to the content provider on behalf of the user by passing that access token as part of the request (as a query argument, HTTP header, or POST form data).

If the content service is accessed only over SSL, we're done. If it's available via plain HTTP, we'd like to protect that permanent access token in some way. Anyone sniffing the connection would be able to get access to the user's content forever.

The way that's solved in OAuth 2 is with a refresh token. The refresh token becomes the permanent password equivalent, and it's only ever transmitted over SSL. When the server needs access to the content service, it exchanges the refresh token for a short-lived access token. That way all sniffable HTTP accesses are made with a token that will expire. Google is using a 5 minute expiration on their OAuth 2 APIs.

So aside from the refresh tokens, OAuth 2 simplifies all the communications between the client, server, and content provider. And the refresh tokens only exist to provide security when content is being accessed unencrypted.

Two-legged authentication

Sometimes, though, a server just needs to control access to its own content. Two-legged authentication allows the client to authenticate the user directly with the server.

OAuth 2 standardizes some extensions to OAuth 1 that were in wide use. The one I know best was introduced by Twitter as xAuth. You can see it in OAuth 2 as Resource Owner Password Credentials.

Essentially, if you can trust the client with the user's credentials (username and password), they can exchange those directly with the content provider for an access token. This makes OAuth much more useful on mobile apps--with three-legged authentication, you have to embed an HTTP view in order to handle the authorization process with the content server.

With OAuth 1, this was not part of the official standard, and required the same signing procedure as all the other requests.

I just implemented the server side of OAuth 2 with Resource Owner Password Credentials, and from a client's perspective, getting the access token has become simple: request an access token from the server, passing the client id/secret as an HTTP Authorization header and the user's login/password as form data.

Advantage: Simplicity

So from an implementor's perspective, the main advantages I see in OAuth 2 are in reduced complexity. It doesn't require the request signing procedure, which is not exactly difficult but is certainly fiddly. It greatly reduces the work required to act as a client of a service, which is where (in the modern, mobile world) you most want to minimize pain. The reduced complexity on the server->content provider end makes it more scalable in the datacenter.

And it codifies into the standard some extensions to OAuth 1.0a (like xAuth) that are now in wide use.

念﹏祤嫣 2024-12-13 18:32:40

首先,正如 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 提供程序。

这篇文章的答案 vonc

First, as clearly indicated in OAuth authentication

OAuth 2.0 is not an authentication protocol.

Authentication in the context of a user accessing an application tells an application who the current user is and whether or not they're present. A full authentication protocol will probably also tell you a number of attributes about this user, such as a unique identifier, an email address, and what to call them when the application says "Good Morning".

However, OAuth tells the application none of that.
OAuth says absolutely nothing about the user, nor does it say how the user proved their presence or even if they're still there.
As far as an OAuth client is concerned, it asked for a token, got a token, and eventually used that token to access some API. It doesn't know anything about who authorized the application or if there was even a user there at all.

There is a standard for user authentication using OAuth: OpenID Connect, compatible with OAuth2.

The OpenID Connect ID Token is a signed JSON Web Token (JWT) that is given to the client application along side the regular OAuth access token.
The ID Token contains a set of claims about the authentication session, including an identifier for the user (sub), the identifier for the identity provider who issued the token (iss), and the identifier of the client for which this token was created (aud).

In Go, you can look at coreos/dex, an OpenID Connect Identity (OIDC) and OAuth 2.0 Provider with Pluggable Connector.

Answer from this post vonc

冷情妓 2024-12-13 18:32:40

我会稍微不同地回答这个问题,而且我会非常精确和简短,主要是因为@Peter T 回答了这一切。

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

  1. 关注点分离。
  2. 将授权与通常服务于业务的 Web 应用程序解耦。

通过这样做,

  1. 您可以实现单点登录的替代方案:如果您有多个信任一个 STS 的应用程序。我的意思是,所有应用程序的一组凭据。
  2. 您可以使您的 Web 应用程序(客户端)能够访问属于您且不属于 Web 应用程序(客户端)的资源。
  3. 您可以将授权过程委托给您信任的第三方,而无需担心用户真实性验证。

I would answer this question slightly differently, and I will be very precise and brief, mainly because @Peter T answered it all.

The main gain that I see from this standard is to respect two principles:

  1. Separation of concerns.
  2. Decoupling authorization from the web application, which usually serves business.

By doing so,

  1. You can implement an alternative to Single SignOn: If you have multiple applications that trust one STS. What I mean, one set of credentials for all applications.
  2. You can enable your web application (The client) to access resources that belong to you and do not belong to the web application (The client).
  3. You can mandate the authorization process to a third party that you trust, and never worry about user authenticity validation.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文