两个工作流程有什么区别?何时使用授权码流程?

时间:2013-05-01 15:44:56

标签: oauth oauth-2.0

OAuth 2.0有多个工作流程。我对这两个问题有几个问题。

  1. 授权代码流 - 用户从客户端应用程序登录,授权服务器向应用程序返回授权代码。然后,应用程序会交换访问令牌的授权码。
  2. 隐式授权流程 - 用户从客户端应用程序登录,授权服务器直接向客户端应用程序发出访问令牌。
  3. 这两种方法在安全性方面有什么区别?哪一个更安全,为什么?

    当服务器可以直接发出访问令牌时,我没有看到为什么在一个工作流中添加额外步骤(令牌的交换授权代码)的原因。

    不同的网站表示,当客户端应用可以保证凭据安全时,会使用授权代码流。为什么呢?

9 个答案:

答案 0 :(得分:183)

access_token是调用受保护资源(API)所需的。在授权代码流程中,有两个步骤可以获得它:

  1. 用户必须进行身份验证并向API使用者(称为“客户端”)返回code
  2. API的“客户”(通常是您的网络服务器)与code交换#1获得的access_token,使用client_idclient_secret对自身进行身份验证
  3. 然后可以使用access_token
  4. 调用API

    因此,有一个双重检查:拥有通过API浮出资源的用户和使用API​​的客户端(例如网络应用程序)。两者都经过验证可以获得授权。请注意OAuth的“授权”性质:用户授予对应用程序的资源访问权限(通过身份验证后返回的code),应用程序获取access_token,然后代表用户进行呼叫。 / p>

    在隐式流程中,省略步骤2。因此,在用户身份验证之后,将直接返回access_token,您可以使用该access_token来访问资源。 API不知道谁在调用该API。任何拥有client id的人都可以,而在前面的例子中只有网络应用程序(它的内部结构通常不会被任何人访问)。

    隐式流通常用于不建议存储client secret和{{1}}的情况(例如设备,尽管很多人都这样做)。这就是免责声明的含义。人们可以访问客户端代码,因此可以获取凭据并假装成为资源客户端。在隐式流程中,所有数据都是易失性的,并且应用程序中没有任何内容存储。

答案 1 :(得分:49)

我会在这里添加一些我认为在上述答案中没有说清楚的内容:

  • 授权代码流允许最终的访问令牌永远不会到达并且永远不会存储在使用浏览器/应用程序的计算机上。临时授权代码通过浏览器/ app提供给计算机,然后发送到服务器。然后,服务器可以使用完全访问令牌进行交换,并可以访问API等。使用浏览器的用户只能通过带有令牌的服务器访问API。
  • 隐式流只能涉及两方,而最终访问令牌通过浏览器/应用程序存储在客户端上。如果此浏览器/应用程序受到威胁,那么他们的身份验证令牌可能是危险。

tl; dr 如果您不信任用户计算机持有令牌但 信任您自己的服务器,则不使用隐式流。

答案 2 :(得分:13)

两者之间的区别在于:

  1. 在Implicit流中,令牌直接通过带有“#”符号的重定向URL返回,这主要用于javascript客户端或没有服务器端的移动应用程序,客户端不需要在某些实施中提供其秘密。

  2. 在授权代码流程中,代码以“?”返回如果服务器端可以读取,则服务器端必须在此时向令牌URL提供客户端密钥,以便从授权服务器获取令牌作为json对象。它用于以下情况:如果您有可以处理此问题的应用程序服务器,并将用户令牌与他/她的配置文件存储在他自己的系统上,并且主要用于常见的移动应用程序。

  3. 所以它取决于客户端应用程序的性质,哪一个更安全的“授权代码”,因为它在客户端请求秘密,并且令牌可以在非常安全的连接上在授权服务器和客户端应用程序之间发送,并且授权提供程序可以限制某些客户端仅使用“授权代码”并禁止隐式

答案 3 :(得分:3)

隐式授权类似于授权代码授予,具有两个明显的差异。

它旨在用于基于用户代理的客户端(例如单页Web应用程序),这些客户端无法保密客户端,因为所有应用程序代码和存储都可以轻松访问。

其次,授权服务器返回一个访问令牌的授权代码,而不是授权服务器返回一个访问令牌的授权代码。

请在此处查找详细信息 http://oauth2.thephpleague.com/authorization-server/which-grant/

答案 4 :(得分:1)

让我总结一下我从上述答案中学到的几点,并加上我自己的一些理解。

授权代码流程!!!

  • 如果您的Web应用程序服务器充当OAuth客户端
  • 如果您想要长期访问
  • 如果您想离线访问数据
  • 当您对应用程序生成的API调用负责时
  • 如果您不想泄露OAuth令牌
  • 如果您不希望应用程序每次需要访问数据时都运行授权流程。注意:Implicit Grant流程不接受刷新令牌,因此如果授权服务器定期访问令牌,您的应用程序将需要在需要访问时运行授权流程。

隐含授权流程!!!

  • 如果没有Web应用程序服务器作为OAuth客户端
  • 如果您不需要长期访问,则只需要临时访问数据。
  • 如果您信任运行应用程序的浏览器,则访问令牌会泄露给不受信任的用户的可能性有限。

答案 5 :(得分:1)

隐含流量

优点

  • 最简单的实施

缺点

  • 访问浏览器可见的令牌
  • 无法确定访问令牌的来源
  • 访问令牌无法过期(按照Google政策)

授权代码流程

优点

  • 最安全
  • 只有知道共享密钥才能创建访问令牌和刷新令牌
  • 可以使用新的安全性和UX功能进行增强

缺点

  • 必须实现多个身份验证端点

引文:https://developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows

答案 6 :(得分:0)

从实际角度来看(我的理解),拥有Authz代码流程的主要原因是:

  1. 支持刷新令牌(代表用户对应用程序进行长期访问),隐式不支持:参考:https://tools.ietf.org/html/rfc6749#section-4.2
  2. 支持同意页面,这是资源所有者可以控制提供的访问权限的地方(您在谷歌中看到的权限/授权页面类型)。同样不是隐含的。请参阅:https://tools.ietf.org/html/rfc6749#section-4.1,点(B)
  3. 部分

    “授权服务器验证资源所有者(通过用户代理)并确定资源所有者是否授予或拒绝客户端的访问请求”

    除此之外,使用刷新令牌,应用程序可以获得对用户数据的长期访问。

答案 7 :(得分:0)

  

哪个更安全,为什么?

它们都是安全的,这取决于您使用它的环境。

  

我看不出为什么需要执行额外步骤(交换授权码)的原因   服务器可以直接在一个工作流程中添加令牌)   发出访问令牌。

很简单。您的客户不安全。让我们详细看看。

考虑到您正在针对Instagram API开发应用程序,因此您要向Instagram注册APP并定义所需的API'sInstagram将为您提供client_idclient_secrect

在您的网站上,您设置了一个链接,上面写着。 “来并使用我的应用程序”。单击此Web应用程序应该对Instagram API进行两次调用。

First使用以下参数向Instagram Authentication Server发送请求。

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

您没有发送client_secret ,您无法信任客户端(尝试使用您的应用程序的用户和/或他的浏览器)。客户端可以看到url或Java脚本,并轻松找到您的client_secrect。这就是为什么您需要进一步的步骤。

您会收到codestate。这里的codetemporary,没有保存在任何地方。

然后(从您的服务器)对second进行Instagram API调用

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

由于是从我们的服务器发出呼叫,因此我们可以安全地将client_secretcode一起使用client_id(这表明用户已使用access_token来使用资源)。

作为回应,我们将有- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { ImgCollectionCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionCell" forIndexPath:indexPath]; Mainimg.image = cell.img.image; }

答案 8 :(得分:0)

到目前为止,似乎有两个关键点尚未讨论,这解释了为什么授权码授予类型中的绕行增加了安全性。

短篇小说:授权代码授予类型保留浏览器历史记录中的敏感信息,令牌的传输仅取决于授权服务器的HTTPS保护。

长版:

在下文中,我将坚持使用RFC(快速阅读)中定义的OAuth 2术语:资源服务器客户端授权服务器资源所有者

假设您希望某些第三方应用程序(=客户端)访问您的Google帐户(=资源服务器)的某些数据。假设Google使用OAuth2。您是Google帐户的资源所有者,但是现在您正在操作第三方应用。

首先,客户端打开浏览器,将您发送到Google授权服务器的安全URL。然后,您批准访问请求,授权服务器将您发送回客户端先前提供的重定向URL,其中授权代码位于查询字符串中。现在有两个关键点:

  1. 此重定向的URL最终出现在浏览器历史记录中。因此,我们在这里不希望使用可直接使用的令牌。短暂的授权码在历史上危险性较小。请注意,隐式授予类型确实将令牌放入历史记录。
  2. 此重定向的安全性取决于客户端的HTTPS证书,而不取决于Google的证书。因此,我们获得了客户端的传输安全作为额外的攻击媒介(为避免这种情况的发生,不可避免的是,客户端必须是非JavaScript的。否则,我们可以通过片段URL传输授权代码,而该代码不会这可能就是为什么确实使用片段URL的“隐式授予类型”曾经被推荐给JavaScript客户端的原因,即使现在不再如此。)

使用授权码授予类型,令牌最终是通过从客户端到授权服务器的调用获得的,其中传输安全性仅取决于授权服务器,而不取决于客户端