提问者:小点点

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


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

据我所知,有两种可能性。

“正确”的一个是:

  1. 移动应用程序存储client_id
  2. 移动应用程序从GET/auth开始接收authorization_code
  3. 授权服务器返回响应,重定向到redirect_uri并附加授权代码。我们假设,redirect_uri是我们自己服务器上的endpoint
  4. 移动应用程序遵循重定向
  5. 我们的服务器接收请求,从查询中获取authorization_code,并使用POST/token方法和client_secret(存储在服务器上)将其交换为access_token
  6. 服务器使用access_token响应移动应用程序
  7. 移动应用程序接受access_token并在将来的请求中使用它

“坏”的一面是:

  1. 移动应用程序存储client_id和client_secret
  2. 移动应用程序从GET/auth开始接收authorization_code
  3. 授权服务器返回响应,重定向到redirect_uri并附加授权代码。我们假设应用程序拦截它并获取authorization_code(我们可以简单地请求重定向到localhost)
  4. 移动应用程序使用POST/token方法和client_secret将其交换为access_token
  5. 移动应用程序接受access_token并在将来的所有请求中使用它

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

即使一些坏蛋会发布假应用程序……什么可以禁止他们使用我们服务器的回调来交换access_token的授权代码?我们的服务器无法区分“坏”和“好”应用程序-它只接收请求GET\callback?code=blablabla并用access_token回复。

那么我们为什么要在服务器上保密呢?伪造申请的欺诈案例是什么?


共2个答案

匿名用户

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

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

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

对于第一种情况,你不需要在你的应用程序中存储客户端ID或客户端密码,因为它将是你自己的后端服务器,与授权服务器和资源服务器进行通信。如果是这种情况,那么您可以遵循授权代码流程。

对于案例2,与授权和资源服务器通信的将是应用程序本身。在这种情况下,建议使用隐式流。它不被认为是一个安全的流程,移动设备或Web应用程序也不被视为存储客户端机密的安全场所,因为无论如何,你必须将它们存储在应用程序的代码中。下面是一个(有点令人费解)的场景来解释为什么这不安全:客户端机密是由授权服务器或服务注册中心发布的,任何黑客都会要求您更改它,这可能意味着更改代码。对于移动应用程序,这意味着你的用户将更新到新版本。似乎被广泛建议作为额外的安全步骤(而不是客户端机密)的是使用“state”或“nonce”字段,以确保授权请求来自令牌颁发到的同一应用程序。来自RFC第4.1.1节(https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1):

状态

     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.

要在状态字段中传递的值取决于发出请求的人员。您可以生成随机(或伪随机)数。授权服务器发回的回复将使状态字段的填充方式与客户端发送的方式完全相同。然后,您可以将收到的州字段与您发送的州字段进行匹配,以查看它们是否匹配。

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

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

这个帖子很好的解释了OAuth的不同流程:https://www . digital ocean . com/community/tutorials/an-introduction-to-OAuth-2

匿名用户

We assume, that redirect_uri is an endpoint on our own server.

我认为您在这里混淆了客户机和资源服务器的角色。当然,您的资源服务器(承载API的服务器)不应将令牌返回给移动应用程序(客户端),因为它首先需要该令牌来验证客户端。

在OAuth2中,客户端应该在与资源服务器通信之前从授权服务器获取令牌。

它可以使用隐式授权或授权码授权。在后一种情况下,它应该在不提供客户端机密的情况下使用授权,因为移动客户端被认为是不能安全存储机密的公共客户端。