security - 为什么我不应该在 OAuth 2.0 的移动应用程序中保留 client_secret (授权代码授予流程)

标签 security mobile oauth-2.0

我们有一个应用程序,它应该通过第 3 方 OAuth 2.0 服务器(充当授权服务器)使用身份验证。

据我了解,有两种可能性。

“正确”的是:

  1. 移动应用商店client_id
  2. 移动应用以 GET/auth 启动以接收授权码
  3. 授权服务器返回响应并重定向至redirect_uri 并附上授权码。我们假设,redirect_uri 是一个 我们自己的服务器上的端点。
  4. 移动应用遵循重定向
  5. 我们的服务器接收请求,从查询中获取授权码并 使用 POST/token 方法将其交换为 access_token 并 client_secret(存储在服务器上)。
  6. 服务器使用 access_token 对移动应用进行响应
  7. 移动应用获取 access_token 并在将来的请求中使用它。

“坏”的是:

  1. 移动应用商店 client_id 和 client_secret
  2. 移动应用以 GET/auth 启动以接收授权码
  3. 授权服务器返回响应并重定向至redirect_uri 并附上授权码。我们假设,该应用程序 拦截它并获取authorization_code(我们可以简单地要求 重定向到本地主机)。
  4. 移动应用程序使用 POST/token 方法将其交换为 access_token 和 client_secret。
  5. 移动应用获取 access_token 并在以后的所有请求中使用它。

所以我看不出这两种选择之间的真正区别。在这两种情况下,我们最终都会得到访问 token 。在这两种情况下,我们都需要真实用户在相当安全的 WebView 中输入他的登录名和密码。

即使一些坏人会分发假应用程序...如何阻止他们使用我们服务器的回调来交换 access_token 的授权代码?我们的服务器无法区分“坏”和“好”应用程序 - 它只是接收请求 GET\callback?code=blablabla 并使用 access_token 进行回复。

那么我们为什么要在服务器上保密呢?伪造应用程序的欺诈情况如何?

最佳答案

通过 OAuth,您可以根据需要/设置使用不同的流程。根据不同的流程,OAuth 角色的行为也会有所不同。

根据您的描述,我不完全确定客户将扮演什么角色。但选项是:

  1. 后端服务器是客户端
  2. 移动应用是客户端

对于情况 1,您不需要在应用程序上存储客户端 ID 或客户端 key ,因为它将是您自己的后端服务器,用于与授权服务器和资源服务器进行通信。如果是这种情况,那么您可以按照授权代码流程进行操作。

对于情况 2,应用程序本身将与授权和资源服务器进行通信。在这种情况下,推荐使用隐式流。它不被认为是安全的流程,并且移动设备或网络应用程序不被认为是存储客户端 key 的安全位置,因为您必须以某种方式将它们存储在应用程序的代码中。 解释为什么这不安全的一个(有点复杂的)场景如下:客户端 key 由授权服务器或服务注册表颁发,任何黑客行为都需要您更改它,这可能意味着更改代码。对于移动应用程序,这意味着您的用户更新到新版本。 似乎广泛建议作为额外的安全步骤(而不是客户端 key )的是使用“状态”或“随机数”字段来确保授权请求来自颁发 token 的同一应用程序。 来自 RFC 第 4.1.1 节 ( https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1 ):

state

     RECOMMENDED.  An opaque value used by the client to maintain
     state between the request and callback.  The authorization
     server includes this value when redirecting the user-agent back
     to the client.  The parameter SHOULD be used for preventing
     cross-site request forgery as described in Section 10.12.

状态字段中传递的值取决于发出请求的人。您可以生成一个随机(或伪随机)数。授权服务器发回的回复将按照客户端发送的方式准确填写状态字段。然后,您可以将收到的州字段与发送的州字段进行匹配,看看它们是否匹配。

您可以采取的另一个步骤是让客户端发送带有 token 请求的重定向 URI。这很有用,因此授权服务器可以验证请求中的重定向 URI 是否与其与客户端 ID 关联的 URI 匹配。如果您使用的是第三方授权服务器,您应该检查它是否有此行为。

作为最后的安全建议,在与授权服务器或资源服务器通信时始终使用 HTTPS

这篇文章很好地解释了 OAuth 的不同流程:https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

关于security - 为什么我不应该在 OAuth 2.0 的移动应用程序中保留 client_secret (授权代码授予流程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33436767/

相关文章:

iphone - Android 或 iPhone 上的应用内导览/教程/演练的好例子

java.security.Provider.getService(String, String) Java 监视器被阻止

node.js - 在项目中安装包后运行 npm 脚本

java - 保护数据库中的敏感数据,使用 H2 值得吗?

html - 方向改变时如何重新加载网页?

php - 使用 php 在 json 中返回一个数组?

google-app-engine - 来自 Google Developer Console 的 .p12 文件的 PyCrypto 错误

Azure B2C - 使用 PostMan 请求具有多个应用程序范围的 token

java - 如何添加一个没有 xml 配置的 RequestContextListener?

security - 一种以上加密算法的组合