“资源所有者密码流程”和“客户凭证流程”之间的区别

Posted

技术标签:

【中文标题】“资源所有者密码流程”和“客户凭证流程”之间的区别【英文标题】:Difference between the "Resource Owner Password Flow" and the "Client Credentials Flow" 【发布时间】:2014-03-31 09:53:12 【问题描述】:

“资源所有者密码流程”和“客户凭据流程”之间的区别对我来说似乎不清楚。前者似乎将密码凭证转发给服务器进行验证,而后者也以某种方式与服务器进行身份验证,但规范没有指定这里使用什么方法。这个流程是为 cookie 会话设计的吗?规范并没有真正提供明确的用例。

来自 OAuth 2.0 规范:

 +---------+                                  +---------------+
 |         |                                  |               |
 |         |>--(A)- Client Authentication --->| Authorization |
 | Client  |                                  |     Server    |
 |         |<--(B)---- Access Token ---------<|               |
 |         |                                  |               |
 +---------+                                  +---------------+

                 Figure 6: Client Credentials Flow

 +----------+
 | Resource |
 |  Owner   |
 |          |
 +----------+
      v
      |    Resource Owner
     (A) Password Credentials
      |
      v
 +---------+                                  +---------------+
 |         |>--(B)---- Resource Owner ------->|               |
 |         |         Password Credentials     | Authorization |
 | Client  |                                  |     Server    |
 |         |<--(C)---- Access Token ---------<|               |
 |         |    (w/ Optional Refresh Token)   |               |
 +---------+                                  +---------------+

        Figure 5: Resource Owner Password Credentials Flow

【问题讨论】:

【参考方案1】:

This 是最接近该问题的答案。但是,没有一个答案提供了更清晰的例子:

    当一台机器需要访问它在另一台机器上拥有的资源时,您必须使用客户端凭据授权。 当机器需要访问属于最终用户(不是机器)的资源时,需要使用Resource Owner Password Credentials Grant(实际上没有,最好使用Authorization Code Grant) 代表该用户。

在这两个流程之间进行选择时,您应该问自己的关键问题是谁拥有要访问的资源。如果它属于机器(客户端),那么你需要第一个选项,如果它不属于机器,但属于机器将代表其执行请求的用户,那么你需要第二个选项。

【讨论】:

【参考方案2】:

其他答案很好地解释了“资源所有者密码流程”。所以我将解释“Client_credentials”授权类型流程。在“Client_credentials”流程中,client_idclient_secret 用于验证 Client 而不是 Resource owner。因此,您可以在没有资源所有者身份验证的情况下询问客户端(大多数情况下是应用程序)如何获得对资源的访问权限。这是个好问题。答案是,这里客户端将获得 access_token 以获得它自己的资源或访问已在此 client_id 下提供的用户资源。 client_secret 和 client_id 生成大部分时间是手动过程。例如看看这个 -> Create a client ID and client secret for google APIs。在客户端密码创建步骤中,您正在为您的应用程序创建身份验证凭据。

【讨论】:

【参考方案3】:

客户端凭据流仅需要 client_id 和 client_secret。资源所有者流程需要用户密码。

客户端凭据流允许应用程序在不考虑用户上下文的情况下获取令牌。

【讨论】:

但仍不清楚如何获得授权(client_id和client_secret) 请注意不再推荐RO流scottbrady91.com/OAuth/… *资源所有者流程需要用户的密码。" - 我认为进一步澄清这一点会有所帮助。资源所有者流程需要用户的用户名、密码以及客户端的 client_id 和 client_secret。 【参考方案4】:

一个很好的例子如下:

假设您是一家名为 AllStats 的统计公司,拥有自己的用户群,其中每个用户都有自己的用户名和密码。 AllStats 拥有自己的现有网站,其中包含自己的 API。然而,AllStats 现在想要发布一个移动应用程序。

由于移动应用程序将是第一方应用程序(请参阅:由 AllStats 开发),因此资源所有者密码流程非常有意义。您将希望用户获得与应用程序一起流动的屏幕(用户名、密码),而不是将它们踢到身份验证服务器(然后返回应用程序)。用户在输入用户名/密码时会信任该应用程序,因为它是第一方应用程序。

我喜欢将资源所有者密码流视为第一方应用开发者将使用的流,而将客户端凭据流视为第三方应用开​​发者将使用的流。

想象一下,如果 Facebook 应用程序要求您使用客户端凭据流程,而不是仅仅向您提供用户名/密码表单。看起来有点奇怪,是吗?

现在,假设您下载了一个集成了 Facebook 的第三方应用。如果应用程序提示您输入用户名/密码而不是使用客户端凭据流 UI,我想您(和大多数人)会非常谨慎。

FWIW,这并不是说第一方应用不使用客户端凭据流。而是尝试描绘何时使用资源所有者密码流的真实场景(和总体概括)。

【讨论】:

我认为您将“客户端凭据”流程与“授权码”授权混淆了。事实上,“客户端凭据”授权甚至不需要用户名/密码,也没有您提到的“客户端凭据 UI”,因为它用于机器对机器的身份验证。 关于第一方应用程序和资源所有者密码流的部分清晰正确,但您可能将客户端凭据流误认为隐式流? 我不喜欢为移动应用程序使用资源所有者密码,因为它是一个公共客户端(您的客户端密码可能会在资源所有者站点上泄露)。所以那个坏人,可以使用这个资源所有者密码流来进行暴力密码攻击。我认为所有者密码流应该在第一个应用程序中仅作为私人客户端使用。 好的,我正在为我的业务需求实施第一方移动应用程序。移动应用程序是一种私有的 - 它是在我的业务中开发的。我还得到了具有相同特征的 Web 应用程序。我需要用于下一级分层系统的 API - 我可以使用资源所有者密码流进行身份验证吗?我知道 OAuth 定义了授权,而不是身份验证,但是这个解决方案有什么问题?谢谢 没有Client Credential Flow UI【参考方案5】:

除了 user3287829 的回答。我想添加以下内容。

正如RFC 所说的关于客户端凭据授予。

客户端通过添加向令牌端点发出请求 以下参数使用“application/x-www-form-urlencoded” HTTP 中字符编码为 UTF-8 的附录 B 格式 请求实体主体:

grant_type 必需的。值必须设置为“client_credentials”。

范围 可选的。访问请求的范围由 第 3.3 节。

客户端必须通过授权服务器进行身份验证 在第 3.2.1 节中描述。​​

例如,客户端使用发出以下HTTP请求 传输层安全性(带有额外的换行符用于显示目的 仅):

 POST /token HTTP/1.1
 Host: server.example.com
 Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
 Content-Type: application/x-www-form-urlencoded

 grant_type=client_credentials

授权服务器必须对客户端进行身份验证。

客户端必须提前在授权服务器中注册。而Authorization 包括将由服务器进行身份验证的客户端凭据。

【讨论】:

【参考方案6】:

此外,在审计方面,资源所有者是更好的方法,因为您可以通过 access_token 识别哪个特定用户通过客户端应用程序调用您的 api,而 client_credential 仅识别应用程序客户端

【讨论】:

识别(/验证)用户是否完全超出了 OAuth2 的范围? "OAuth 2.0 is not an authentication protocol"。我认为 OpenID Connect 是 OAuth 2 之上身份验证的最佳匹配。 在大多数情况下你不应该使用 ROPC scottbrady91.com/OAuth/… 客户端凭据的全部意义在于没有用户的概念,所以不知道你要去哪里 事实上,有一些用例没有用户参与并与系统交互,但是我已经看到很多例子表明特定用户与系统“A”交互并且在这种情况下,系统“A”调用系统“B”,当然,如果可能的话,我更愿意尝试对特定用户进行识别。所以,我不是在批评 OAuth 2 客户端凭据协议,我只是在解释惰性方式是客户端凭据在某些情况下可以考虑对特定用户 bwteen 2 系统进行身份验证。你明白了吗?这是我的观点。 不过这是一篇很老的帖子了!大声笑,现在有一些关于 oauth2 使用和安全问题的文章。

以上是关于“资源所有者密码流程”和“客户凭证流程”之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

String oauth 2 资源所有者密码流程——交换了用户名和客户端 ID

Keycloak 客户凭证流程说明

页面刷新时不存在授权标头

UNION和UNION ALL两者之间在性能上的区别

“,”和“;”有啥区别?

Statement和PreparedStatement之间的区别