手机上的OAuth使用代理服务器是不是太麻烦了?

发布于 2024-11-02 11:55:32 字数 2811 浏览 1 评论 0原文

过去几天我一直在启动并运行 OAuth 实施。不是在 Android 上,而是在我的 Web 服务器上,该服务器将充当 OAuth 受保护服务的代理。我正要实现我的 Android 客户端,但我的脑子里仍然在思考安全和实现问题。

当客户端只是一个 Web 浏览器时,OAuth 就够混乱的了。您有以下一系列步骤:(

  • 客户端 Web 浏览器)向我的代理服务器发出请求
  • (代理服务器)从 OAuth 提供商请求未经授权的令牌(例如 Web 服务 API)
  • (代理服务器)要求 OAuth 提供商让用户授权令牌。 用户完成授权后,将 Web 浏览器重定向到 OAuth 提供商的“授权”URI
  • (OAuth 提供商),将浏览器重定向到您的回调 URI
  • (代理服务器::回调 URI) 将授权令牌交换为访问令牌,然后存储它以供将来调用
  • 进行 API 调用到 OAuth 提供商并将响应文档返回到客户端 Web 浏览器

现在这已经足够了。但是,当作为客户端在移动应用程序中使用相同的机制时,它会变得更加复杂。当然,问题是您必须在进行 OAuth 舞蹈时执行一些操作才能将浏览器会话注入到移动应用程序的代码流中。这意味着您必须使 OAuth 舞蹈进一步复杂化,如下所示(我在本示例中使用 Android 应用程序来使事情具体化):(

  • 从代理服务器发出请求
  • 移动 Web 应用程序::本机代码)使用 Java/HTTP (代理服务器) 从 OAuth 提供者(例如 Web 服务 API)
  • (代理服务器)请求未经授权的令牌,将响应文档返回到移动 Web 应用程序,其中包含 OAuth 提供者用于用户授权的重定向 URI,最好进行混淆以隐藏消费者密钥和其他详细信息阻止“空中”窥探。
  • (移动 Web 应用程序)使用安装了 Intent 过滤器的授权 URL 启动 Web 浏览器活动。但是,存储代理服务器的指定回调 URI,然后将其替换为特殊的“虚假”URI,该 URI 旨在通过意图过滤器轻松识别 URI(请参阅以下步骤)
  • (OAuth 提供程序),在用户完成授权后,将浏览器重定向到您的“虚假”回调URI。
  • (移动网络应用程序)意图过滤器检测“虚假”回调 URI 并使用该信号重新获得控制权。重建代理服务器的回调 URI 并使用 Java/HTTP 执行请求。
  • (代理服务器::callback URI)将授权令牌交换为访问令牌,然后像以前一样存储它以供将来
  • 调用对 OAuth 提供程序进行 API 调用并将响应文档返回到移动 Web 应用程序

正如您所看到的,这是相当可怕的。如果有一种更简单的方法可以做到这一点,那么我很想听到它。据我所知,只有两种选择,每种选择都有自己的重大问题。

1) 忘记代理服务器,直接从移动网络应用程序执行所有操作。这里最大的安全漏洞是您必须将 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 Web 浏览器会话安全性进行一些研究时,我很高兴地发现您不允许访问当前网页 HTML。如果您可以访问它,那么恶意的 Android 编码人员就可以轻松嗅出用户的登录名和密码,从而完全破坏 OAuth 的目的和意图。我很沮丧地发现可能有一种方法可以通过 CacheManager 对象获取 HTML。奇怪的是,该对象现在已被弃用,并根据 Android 文档计划删除,因此希望这意味着 Google 发现了(潜在的)安全漏洞,并正在采取措施在即将推出的版本中删除它:

http://developer.android.com/reference/android/webkit/CacheManager.html

最后,我我想听听那些在创建 OAuth 应用程序时遇到这些相同问题的人们的想法。

——罗施勒

I have spent the last few days getting an OAuth implementation up and running. Not on Android, but on my web server that will act as the proxy to the OAuth protected service. I'm just about to implement my Android client and my head is still churning over security and implementation issues.

OAuth is messy enough when the client is just a web browser. You have the following series of steps:

  • (client web browser) make request to my proxy server
  • (proxy server) request unauthorized token from OAuth provider (e.g. - web service API)
  • (proxy server) ask OAuth provider to have user authorize the token. Redirect web browser to OAuth provider's 'authorize' URI
  • (OAuth provider) after user completes authorization, redirects browser to your callback URI
  • (proxy server::callback URI) Exchange authorization token for an access token and then store it for future calls
  • Make API calls to OAuth provider and return response document to client web browser

Now that's quite enough as it is. But when using the same mechanics with a mobile app as a client it gets even more involved. The problem is of course that you have to do some acrobatics to inject a browser session into your mobile app's code flow while doing the OAuth dance. This means you have to further complicate the OAuth dance as follows (I am using an Android app for this example to make things concrete):

  • (mobile web app::native code) make request from proxy server using Java/HTTP
  • (proxy server) request unauthorized token from OAuth provider (e.g. - web service API)
  • (proxy server) return a response document to the mobile web app that contains the redirect URI for user authorization by the OAuth provider, preferably obfuscated to hide the consumer key and other details to deter "over-the-air" snooping.
  • (mobile web app) Launch a web browser activity with the authorization URL with an intent filter installed. However, store and then replace the proxy server's specified callback URI with a special "phony" URI crafted for easy URI identification by an intent filter (see following steps)
  • (OAuth provider) after user completes authorization, redirect browser to your "phony" callback URI.
  • (mobile web app) Intent filter detects "phony" callback URI and uses that signal to regain control. Rebuild the proxy server's callback URI and use Java/HTTP to execute the request.
  • (proxy server::callback URI) Exchange authorization token for an access token and then store it for future calls as before
  • Make API calls to OAuth provider and return response document to mobile web app

This is rather hideous as you can see. If there is a much simpler way of doing this then I am eager to hear it. As far as I know there only two other alternatives, each with their own significant problems.

1) Forget about a proxy server and do everything directly from the mobile web app. The big security hole here is that you have to "bake" in your OAuth consumer key and secret into your app. If an attacker decompiles your code and hunts down those strings, a fairly easy operation for someone who is experienced at reverse engineering, they can wreak havoc with your application and users.

2) Switch to XAuth where the user provides you with their login name and password, and you "agree" not to store them and exchange them directly for an access token with the XAuth server. The first problem is gaining user trust to provide that information, the problem OAuth was created to solve, and of course what about people that don't honor their commitment to discard the login details? Worse, the XAuth server must support XAuth and offer HTTPS (SSL) connections and I have seen tons of web API's that don't support either. An SSL connection is necessary of course because without it you'd send the user's login name and password over the wire in plain text when making your XAuth request.

http://blog.zyber17.com/post/1283741364/why-xauth-is-a-really-dumb-idea

FYI, although it does not use a proxy server the following example illustrates the technique I described above for injecting a browser session into your mobile app OAuth interaction and intercepting the callback URI:

http://blog.doityourselfandroid.com/2010/11/10/oauth-flow-in-android-app/

So it seems pretty ugly any way you look at it and I didn't even get into the additional annoyance of creating and managing your own user ID for the user so you can look up their access tokens stored on your proxy web server properly (including the messiness of one more PIN or access code for the user to manage).

Interesting side note: When doing some research on an Android web browser session security I was pleased to find out that you are not allowed access to the current web page HTML. If you could access it, then a hostile Android coder could easily sniff out the user's login and password thereby defeating the purpose and intent of OAuth entirely. I was dismayed to find out that there may be a way to get that HTML by way of the CacheManager object. Curiously enough that object is now deprecated and schedule for removal according to the Android docs so hopefully that means Google discovered the (potential) security hole and is taking steps to remove it in an upcoming build:

http://developer.android.com/reference/android/webkit/CacheManager.html

In closing, I'd like to hear the thoughts of those out there that have struggled with these very same issues when creating their OAuth applications.

-- roschler

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ぶ宁プ宁ぶ 2024-11-09 11:55:32

Janrain 发布了一个库,它提供了一些 UI 粘合和代理后端登录系统;它支持许多流行的 OAuth 身份提供商(例如 Google/FB)。在登录流程结束时,您会从设备获得 HTTPS POST,为您提供可交换用户标识符和其他信息的令牌,以及将访问令牌返回到设备的通道。

http://www.janrain.com/products/engage/mobile

https://github.com/janrain/engage.android

披露:我在 Janrain 工作,负责这个库。

Janrain has released a library which provides some UI glue and a proxy backend login system; it supports a bunch of popular OAuth identity providers (e.g. Google/FB). At the end of the sign in flow you get an HTTPS POST from the device supplying you with a token exchangeable for a user identifier and other info, and a channel to return an access token to the device.

http://www.janrain.com/products/engage/mobile

https://github.com/janrain/engage.android

Disclosure: I work at Janrain, on this library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文