我正在开发一个通过带有Spring的OAuth2保护的REST API,它将从Android应用程序(客户端)使用。为了访问我的 API 的任何端点,需要一个 OAuth2 访问令牌,并通过授权标头以类似于如下的方式移交给端点:
"授权" - "持有者访问令牌">
要获取访问令牌,必须提供用户名和密码,以及客户端 ID 和客户端密钥(它们代表 Android 应用)。clientID 和客户端密钥通过授权标头以类似于 Spring 指定的方式移交给令牌端点:
"授权" - "基本客户端 ID:客户端机密">
如果客户端 ID 和客户端密钥与服务器上定义的客户端匹配,并且用户存在且密码正确,则返回访问令牌和刷新令牌。
现在我的问题是,如何将我的 clientId 和客户端密钥安全地存储在Android 应用程序中,确保对我的应用程序进行逆向工程的人无法访问它们?
此外,如果我要开发 iOS 应用程序(第二个客户端),使用与安全 POV 不同的客户端 ID 和客户端密钥是否明智?
你不能 - 即使有办法,我仍然可以检查线路上的有效载荷以确定值。请参阅适用于本机应用程序的 OAuth 2.0 的第 8.5 节
作为分发给多个用户的应用的一部分静态包含的机密不应被视为机密机密,因为一个用户可以检查其副本并了解共享机密。 出于这个原因,以及 [RFC6819] 第 5.3.1 节中所述的原因,不建议授权服务器要求使用共享密钥对公共本机应用程序客户端进行客户端身份验证,因为这除了客户端标识之外几乎没有什么价值,客户端标识是由"client_id"请求参数提供的
。
您的客户端 ID/secret 参数仅提供发出请求的应用程序的标识,因此建议您为 iOS 应用程序创建一个不同的客户端,无论是从安全隔离的角度来看 + 对于您想要收集的有关应用程序使用情况的任何分析(例如,"您通过客户端 ID 检索了多少次登录尝试?
但是,威胁参与者可能会对您的设置进行反向工程,获取您的客户端 ID + 机密,然后开始使用用户名/密码组合命中您的令牌终端节点,以尝试暴力破解您的应用程序。如果端点接受这些值并返回成功/失败代码,则对于试图破坏系统的人来说,这是一个有用的攻击媒介。
当前推荐的方法是使用"授权代码流">
在本机应用中授权用户的当前最佳做法是 在外部用户代理(通常是浏览器)中执行 OAuth 授权请求,而不是在嵌入式用户代理(例如使用 Web 视图实现的用户代理)中执行。
以前,本机应用程序使用嵌入式应用程序是很常见的 OAuth 的用户代理(通常通过 Web 视图实现) 授权请求。 这种方法有很多缺点, 包括能够复制用户凭据的主机应用,以及 Cookie,以及需要在每个 Cookie 中从头开始进行身份验证的用户 .app。 有关使用嵌入式的更深入分析,请参见第 8.12 节 OAuth 的用户代理。
查看 AppAuth for Android 了解更多信息,