Jai*_*ime 5 security oauth oauth-2.0 spring-security-oauth2 flutter
我正在开发一个带有 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 等都有使用限制,我不想让我的资源所有者能够在他们想要的时间按下按钮。
这是我的第一个想法的流程:
脚步:
客户端调用授权服务器启动用户代理以进行 oauth 登录。为了让资源拥有者登录并授权。url 和参数是硬编码的,在我的客户端中是硬编码的。
资源所有者登录并授权客户端。
回调是通过代码发送的。
客户端捕获回调代码并向授权服务器发送消息以获取令牌。由于某些授权服务器接受 PKCE,因此我尽可能使用 PKCE,以避免攻击并在客户端中硬编码我的客户端密钥。其他人(例如 Strava)不允许 PKCE,因此我必须在客户端中对客户端密钥进行硬编码才能获取令牌。
将令牌返回给我的客户端后,我将它们发送到我的其余 api 并存储在标识令牌资源所有者的数据库中。
调用资源服务器:
一个定期进程获取每个资源所有者的令牌,并使用从每个资源服务器返回的活动更新我的数据库。
资源所有者调用rest api并获取所有活动。
第一个想法的问题在于,一些授权服务器允许实施 PKCE (Fitbit),而其他授权服务器则使用客户端密钥来创建令牌 (Strava)。由于我需要客户端密钥来获取其中一些授权服务器的令牌,因此我已在客户端中对密钥进行了硬编码,但这并不安全。
我知道将客户端机密插入客户端是危险的,因为黑客可以反编译我的客户端并获取客户端机密。如果授权服务器中不允许 PKCE,我无法弄清楚如何在不硬编码客户端密钥的情况下获取 Strava 的资源所有者令牌。
由于我不想在客户端中对客户端机密进行硬编码,因为它不安全并且我想将令牌存储在我的数据库中,因此我认为第一种方法不是一个好的选择。此外,我正在向 REST API 创建一个 POST 请求,以便将访问令牌和刷新令牌存储在我的数据库中,如果我没记错的话,该过程可以直接从后端完成。
我的情况是,我开发了一个公共客户端(移动应用程序),它对客户端密钥进行了硬编码,因为我不知道当授权服务器不允许 PKCE 获取令牌时如何避免这样做。
因此,在思考所有这些问题之后,我的第二个想法是利用我的 REST API 并从那里调用授权服务器。因此,我的客户将是保密的,我将使用服务器端应用程序执行 OAuth 流程。
我的想法是基于这张图片。
为了避免我的移动客户端中的客户端秘密硬编码,以下基于图像的代码流是否可以工作并安全地连接到 Strava、Garmin、Polar...?
Strava 连接示例:
移动客户端
移动公共客户端调用我的 Rest API 以获取 Strava 授权服务器登录的 URI,并包含所需参数,例如:callback、redirect_uri、client_it 等。
移动客户端捕获 Rest API GET 响应 URI。
移动客户端启动用户代理(Chrome 自定义选项卡)并监听回调。
用户代理
Strava 的登录提示会显示给资源所有者。
资源所有者插入凭据并推送授权。
回调已启动
移动客户端
当我的客户端检测到回调时,返回客户端并从回调 uri 中提取代码。
通过帖子将该代码发送到我的 REST API。(https://myrestapi,代码在正文中)
REST API 客户端
现在,客户端是我的 REST API,因为它将使用移动客户端获取的代码调用授权服务器。客户端将获取该代码,并在其中硬编码客户端密钥,然后调用授权服务器。通过这种方法,客户端秘密不再存在于移动客户端中,因此它是保密的。
授权服务器返回令牌,我将它们存储在数据库中。
过程
第二种方法是处理客户端机密以避免公开的好方法吗?或者我做错了什么?我可以遵循什么流程以正确的方式做到这一点?我真的被这个案例困扰了,而且由于我是 OAuth 世界的新手,我对我读过的所有信息感到不知所措。
您提出的第二种方法是实现 OAuth 流程的有效方法。您的后端可以充当您需要的机密客户端,并且您可以安全地从授权服务器获取令牌。这种模式有时被称为“Backand-For-Frontend”(尽管这个名称现在有点重载)。在 Curity,我们描述了类似的东西,我们称之为令牌处理程序模式。前提是相似的,但我们的主要目标是可以利用 cookie 来管理会话的单页应用程序。
当然,您需要的是在后端和移动应用程序之间创建安全会话。在浏览器应用程序中,您只需使用带有 cookie 的普通旧会话。您必须确保在调用您的后端时没有人可以冒充您的应用程序的用户。
您可以探索的另一件事是 Stravia 是否支持动态客户端注册标准。使用 DCR,您可以将移动应用程序的每个实例注册为单独的客户端。然后,每个客户端都会收到自己的客户端 ID 和密码。这样您就不必担心秘密被窃取。
您还可以联系 Stravia,询问他们为什么不通过 PKCE 支持公共客户以及他们是否计划这样做。PKCE 是一个重要的安全 OAuth 标准,公司应寻求支持它。
| 归档时间: |
|
| 查看次数: |
2055 次 |
| 最近记录: |