如何在本机应用程序上存储 OAuth 客户端 ID

Posted

技术标签:

【中文标题】如何在本机应用程序上存储 OAuth 客户端 ID【英文标题】:How to store OAuth client id on native apps 【发布时间】:2018-11-20 02:53:48 【问题描述】:

我正在开发一个本机应用程序,该应用程序将使用 OAuth 来允许用户登录(或访问材料本身)到另一个网站。我知道我将使用 OAuth 的隐式流程或授权代码流程,但是我所有关于安全性的研究似乎都与客户端机密有关。

我的应用程序的客户端 ID(由第 3 方网站提供)似乎是公开的,因此会公开。这将允许其他人接受它,并按照相同的隐式流程伪装成我的应用程序。这只是 oauth 的本质吗?

有没有办法存储这些信息以免被盗?

编辑: 我想澄清一下 - 我了解 oauth 可以保护用户的信息不受我的应用程序和理想拦截器的影响。但是是什么阻止了某人获取我的客户 ID(因为它通过身份验证过程公开可见)并将其用于自己?开源应用程序是否可以采取任何措施?

【问题讨论】:

请查看this realated question。如果您使用的是客户端 ID,那么您还将使用客户端密码。授权码流应该用在客户端秘密不会暴露给其他人的情况下,例如。 “客户端”(在 OAuth 的意义上)驻留在 Web 服务器上。 @ChristianGawron,我正在开发的应用程序是面向用户的没有后端的客户端 - 这就是为什么使用客户端密码的流程对我不起作用的原因。 “在隐式流程中,所有数据都是易失性的,应用程序中没有存储任何内容” - 在您提供的帖子的答案中提到了这一点,您能否澄清“数据易失性”的含义以及如何这将有助于确保我的应用的客户端 ID 安全吗? 这意味着在隐式流程中,不使用客户端密钥 - 因此您可以在像您这样没有后端以安全方式存储密钥的情况下使用此流程..跨度> 是的,但是客户端 ID 从哪里开始?例如,作为我的代码中的字符串?在由代码解析的配置文件中?当用户被引导离开登录过程时,我的客户端 ID 以基本编码形式可见,不是吗? 【参考方案1】:

无法保护客户端 ID,因为它在授权请求中作为查询参数发送。

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

(您可以在本机应用程序中使用 Web 视图并隐藏地址栏,但随后您的应用程序将有权访问用户的凭据。)

进一步说明:

不建议在本机应用程序中使用隐式流,因为攻击者可以在操作系统上注册您的重定向 URI,并可以使用访问令牌捕获回调。

授权码流是更好的选择。如果您能够将客户端密码安全地存储在您的应用程序中(请参见下面的链接),攻击者可以使用您的客户端 ID 启动授权或捕获回调,但他将无法使用授权代码来获取访问令牌。

链接:

Best practices for storing and protecting private API keys

How to avoid reverse engineering of an APK file

Best practices for implementing OAuth in native applications

RFC for PKCE

【讨论】:

"攻击者可以使用您的客户端 ID 来启动授权或捕获回调":表示 "redirect_uri" 是服务器必须发送授权代码的 uri,每个 redirect_uri 必须事先注册在服务器端,那么如果将授权码发送到注册的redirect_uri(那不是“坏”客户端的uri?),那么坏客户端如何获取authorization_code?​​span> 原生应用可以在操作系统上注册任何 URI。 (至少在 android 上是这样。我不知道这在 ios 上是否允许。)因此,攻击者可以注册相同的 URI 并捕获回调。 (见:tools.ietf.org/html/rfc7636#section-1)

以上是关于如何在本机应用程序上存储 OAuth 客户端 ID的主要内容,如果未能解决你的问题,请参考以下文章

如何将 oauth2 令牌发送给客户端并存储它们?

如何生成 OAuth 2 客户端 ID 和密钥

如何生成 OAuth 2 客户端 ID 和密钥

使用 LDAP 在 Spring oauth/token 请求上验证客户端 ID 和客户端密码

来自本机应用的 Instagram API OAuth

如何存储 Angular 前端使用的 OAuth1 令牌