在过去的几天里,我一直在启动并运行 OAuth 实现。不是在 Android 上,而是在我的 Web 服务器上,它将充当 OAuth 保护服务的代理。我正要实现我的 Android 客户端,但我的头脑仍在为安全和实现问题而烦恼。
当客户端只是一个 Web 浏览器时,OAuth 就够麻烦了。您有以下一系列步骤:
- (客户端网络浏览器)向我的代理服务器发出请求
- (代理服务器)向 OAuth 提供者请求未经授权的令牌(例如 - Web 服务 API)
- (代理服务器)要求 OAuth 提供者让用户授权令牌。将 Web 浏览器重定向到 OAuth 提供者的“授权”URI
- (OAuth 提供者)用户完成授权后,将浏览器重定向到您的回调 URI
- (proxy server::callback URI) 交换访问令牌的授权令牌,然后将其存储以供将来调用
- 对 OAuth 提供者进行 API 调用并将响应文档返回到客户端 Web 浏览器
现在这已经足够了。但是,当将相同的机制与作为客户端的移动应用程序一起使用时,它会变得更加复杂。问题当然是你必须做一些杂技来将浏览器会话注入到你的移动应用程序的代码流中,同时进行 OAuth 舞蹈。这意味着您必须使 OAuth 之舞进一步复杂化,如下所示(我在此示例中使用了一个 Android 应用程序以使事情变得具体):
- (mobile web app::native code) 使用 Java/HTTP 从代理服务器发出请求
- (代理服务器)向 OAuth 提供者请求未经授权的令牌(例如 - Web 服务 API)
- (代理服务器)向移动 Web 应用程序返回一个响应文档,其中包含 OAuth 提供者用于用户授权的重定向 URI,最好进行模糊处理以隐藏消费者密钥和其他详细信息,以阻止“无线”窥探。
- (移动网络应用程序)使用安装了意图过滤器的授权 URL 启动网络浏览器活动。但是,存储代理服务器的指定回调 URI,然后用一个特殊的“假”URI 替换它,以便通过意图过滤器轻松识别 URI(请参阅以下步骤)
- (OAuth 提供者)用户完成授权后,将浏览器重定向到您的“假”回调 URI。
- (移动网络应用程序)意图过滤器检测“虚假”回调 URI 并使用该信号重新获得控制权。重建代理服务器的回调 URI 并使用 Java/HTTP 执行请求。
- (proxy server::callback URI) 交换访问令牌的授权令牌,然后像以前一样存储它以供将来调用
- 对 OAuth 提供者进行 API 调用并将响应文档返回到移动 Web 应用程序
如您所见,这相当可怕。如果有更简单的方法可以做到这一点,那么我很想听到它。据我所知,只有两个其他选择,每个都有自己的重大问题。
1) 忘记代理服务器,直接从移动 Web 应用程序执行所有操作。这里最大的安全漏洞是你必须“烘焙”你的 OAuth 消费者密钥和秘密到你的应用程序中。如果攻击者反编译您的代码并追捕这些字符串,对于具有逆向工程经验的人来说,这是一个相当容易的操作,他们可能会对您的应用程序和用户造成严重破坏。
2)切换到XAuth,用户向您提供他们的登录名和密码,并且您“同意”不存储它们并直接与XAuth服务器交换访问令牌。第一个问题是获得用户信任以提供该信息,创建 OAuth 就是为了解决这个问题,当然还有那些不履行承诺放弃登录详细信息的人呢?更糟糕的是,XAuth 服务器必须支持 XAuth 并提供 HTTPS (SSL) 连接,而且我见过大量的 Web API 也不支持。SSL 连接当然是必要的,因为如果没有它,您将在发出 XAuth 请求时通过网络以纯文本形式发送用户的登录名和密码。
http://blog.zyber17.com/post/1283741364/why-xauth-is-a-really-dumb-idea
仅供参考,尽管它不使用代理服务器,但以下示例说明了我上面描述的将浏览器会话注入您的移动应用程序 OAuth 交互并拦截回调 URI 的技术:
http://blog.doityourselfandroid.com/2010/11/10/oauth-flow-in-android-app/
所以无论你怎么看,它看起来都很难看,我什至没有为用户创建和管理你自己的用户 ID 带来额外的烦恼,这样你就可以正确地查找他们存储在代理 Web 服务器上的访问令牌(包括用户管理的另外一个 PIN 或访问代码的混乱)。
有趣的旁注:在对 Android 网络浏览器会话安全性进行一些研究时,我很高兴地发现不允许您访问当前网页的 HTML。如果您可以访问它,那么恶意的 Android 编码器可以轻松地嗅出用户的登录名和密码,从而完全破坏 OAuth 的目的和意图。我很沮丧地发现可能有一种方法可以通过 CacheManager 对象获取该 HTML。奇怪的是,该对象现在已被弃用并根据 Android 文档计划删除,因此希望这意味着 Google 发现了(潜在的)安全漏洞,并正在采取措施在即将到来的构建中删除它:
http://developer.android.com/reference/android/webkit/CacheManager.html
最后,我想听听那些在创建 OAuth 应用程序时遇到同样问题的人的想法。
——罗施勒