小编Jai*_*ime的帖子

了解 PKCE 与授权代码授予的优势

我是 OAuth 世界的新手,我试图了解使用 PKCE 相对于传统授权代码授予的好处。(我的许多假设可能是错误的,所以感谢您的指正。)

我是一名移动应用程序开发人员,根据 OAuth 文档,客户端机密不能在公共客户端的应用程序代码中进行硬编码。避免对客户端密钥进行硬编码的原因是,黑客可以反编译我的应用程序并获取我的客户端密钥。

黑客利用我的客户端密码和我的redirect_url,可以开发一个虚假的应用程序。如果最终用户 (User1) 下载真实应用程序和黑客的应用程序(两者),则虚假应用程序可以侦听真实应用程序回调并从中获取授权代码。通过授权代码(来自回调)和客户端密钥(通过反编译我的应用程序窃取),黑客可以获取授权令牌和刷新令牌,并能够获取 User1 的数据等。

如果其他用户下载真假应用程序,他们的数据也将面临危险。我对吗?黑客是否需要两者,或者他/她是否可以仅使用授权代码进行攻击?镜像的第五步需要客户端密钥和授权码吗?

这种攻击称为拦截攻击。

在此输入图像描述

为了解决公共客户端应用程序中硬编码客户端密钥的问题,使黑客无法获取客户端密钥并窃取令牌,发明了 PKCE。使用 PKCE,客户端应用程序代码不需要对客户端密钥进行硬编码,因为 PKCE 不需要该信息来获取最终用户的令牌。

PKCE 流程创建一个随机字符串,将其转换为SHA-256哈希值和 Base64。在图像的第二点中,该编码字符串与客户端 id一起发送到身份验证服务器。然后,授权代码在回调中发送,如果任何恶意应用程序拦截该代码,它将无法获取令牌,因为图像的第五点需要由合法应用程序创建的原始随机字符串。

这很好,但如果不再需要客户端密钥来获取令牌来访问 User1 数据,我如何避免黑客开发一个假应用程序,该应用程序使用 PKCE 流和我的客户端 ID 并获取用户的令牌认为该应用程序是合法的?

由于图像的第五步不再需要客户端密钥来获取令牌,任何人都可以使用我的公共客户端 ID 开发虚假应用程序,如果任何用户下载虚假应用程序并执行 OAuth 流程,黑客就可以获取它的令牌并访问该用户的数据!

我对吗?

security oauth token oauth-2.0 pkce

9
推荐指数
1
解决办法
3925
查看次数

如何使用服务器管理移动应用程序中的 OAuth 流程

我正在开发一个带有 flutter(移动客户端)的体育移动应用程序,用于跟踪用户活动数据。跟踪活动(游泳、跑步、步行...)后,它会调用我开发的 REST API(使用 springboot),并通过 POST 传递该活动数据。然后,我的用户将能够通过 GET 调用 REST API 查看其跟踪活动的日志。

由于我知道我自己的跟踪开发不如Strava、Garmin、华为等,所以我想让我的应用程序用户连接他们的Strava、Garmin等帐户以获取他们的活动数据,所以我需要用户授权我的应用程序使用 OAuth 获取该数据。

在第一种方法中,我成功地使用授权代码授予通过 flutter 开发了 OAuth 的所有流程。授权服务器登录由 flutter 在用户代理(chrome 选项卡)中启动,一旦资源所有者完成登录并授权我的 flutter 应用程序,我的 flutter 应用程序就会获取授权代码并调用授权服务器来获取令牌。所以我可以说,我的客户端就是我的 flutter 应用程序。当 oauth 流程完成后,我将令牌发送到 Rest API,以便将它们存储在数据库中。

我的第一个想法是将这些令牌发送到我的后端应用程序,以便将它们存储在数据库中,并开发一个流程,该流程获取这些令牌、咨询资源服务器、将每个资源服务器 json 响应活动解析为我的其余 API 活动模型活动并存储在我的数据库。然后,如果资源所有者调用我的 Rest API 查询其活动,他将获得所有活动的响应(移动应用程序跟踪的活动 + Strava、Garmin、资源服务器等存储在我的数据库中的活动)。

当用户按下同步按钮并直接在客户端中映射这些响应时,我放弃了直接从客户端调用资源服务器和其余 api 的选项,因为我需要后端中这些资源服务器响应的数据为了实现奖牌功能。此外,Strava、Garmin 等都有使用限制,我不想让我的资源所有者能够在他们想要的时间按下按钮。

这是我的第一个想法的流程:

脚步:

  1. 客户端调用授权服务器启动用户代理以进行 oauth 登录。为了让资源拥有者登录并授权。url 和参数是硬编码的,在我的客户端中是硬编码的。

  2. 资源所有者登录并授权客户端。

  3. 回调是通过代码发送的。

  4. 客户端捕获回调代码并向授权服务器发送消息以获取令牌。由于某些授权服务器接受 PKCE,因此我尽可能使用 PKCE,以避免攻击并在客户端中硬编码我的客户端密钥。其他人(例如 Strava)不允许 PKCE,因此我必须在客户端中对客户端密钥进行硬编码才能获取令牌。

  5. 将令牌返回给我的客户端后,我将它们发送到我的其余 api 并存储在标识令牌资源所有者的数据库中。

调用资源服务器:

  1. 一个定期进程获取每个资源所有者的令牌,并使用从每个资源服务器返回的活动更新我的数据库。

  2. 资源所有者调用rest api并获取所有活动。

第一个想法的问题在于,一些授权服务器允许实施 PKCE (Fitbit),而其他授权服务器则使用客户端密钥来创建令牌 (Strava)。由于我需要客户端密钥来获取其中一些授权服务器的令牌,因此我已在客户端中对密钥进行了硬编码,但这并不安全。

我知道将客户端机密插入客户端是危险的,因为黑客可以反编译我的客户端并获取客户端机密。如果授权服务器中不允许 PKCE,我无法弄清楚如何在不硬编码客户端密钥的情况下获取 Strava 的资源所有者令牌。

由于我不想在客户端中对客户端机密进行硬编码,因为它不安全并且我想将令牌存储在我的数据库中,因此我认为第一种方法不是一个好的选择。此外,我正在向 REST API 创建一个 POST …

security oauth oauth-2.0 spring-security-oauth2 flutter

5
推荐指数
1
解决办法
2055
查看次数