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。不是在Android上,而是在我的网络服务器上,它将充当OAuth保护服务的代理。我正准备实施我的Android客户端,而我的头脑仍在努力解决安全性和实施问题。
OAuth is messy enough when the client is just a web browser. You have the following series of steps:
当客户端只是一个Web浏览器时,OAuth就足够混乱了。您有以下一系列步骤:
- (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
(客户端Web浏览器)向我的代理服务器发出请求
(代理服务器)从OAuth提供商请求未经授权的令牌(例如 - Web服务API)
(代理服务器)要求OAuth提供商让用户授权令牌。将Web浏览器重定向到OAuth提供程序的“授权”URI
(OAuth提供商)用户完成授权后,将浏览器重定向到您的回调URI
(代理服务器::回调URI)访问令牌的Exchange授权令牌,然后将其存储以供将来调用
对OAuth提供程序进行API调用并将响应文档返回给客户端Web浏览器
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):
现在这已经足够了。但是当使用与移动应用程序相同的机制作为客户端时,它会更加复杂。问题当然是你必须做一些杂技,以便在进行OAuth舞蹈时将浏览器会话注入到移动应用程序的代码流中。这意味着你必须进一步复杂化OAuth舞蹈如下(我在这个例子中使用Android应用程序来使事情具体化):
- (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
(移动Web应用程序::本机代码)使用Java / HTTP从代理服务器发出请求
(代理服务器)从OAuth提供商请求未经授权的令牌(例如 - Web服务API)
(代理服务器)将响应文档返回到移动Web应用程序,该应用程序包含OAuth提供商用户授权的重定向URI,最好是模糊化以隐藏消费者密钥和其他细节以阻止“无线”窥探。
(移动Web应用程序)使用已安装intent过滤器的授权URL启动Web浏览器活动。但是,存储然后用一个特殊的“假冒”URI替换代理服务器的指定回调URI,以便通过意图过滤器轻松识别URI(请参阅以下步骤)
(OAuth提供商)在用户完成授权后,将浏览器重定向到您的“假冒”回调URI。
(移动网络应用程序)意图过滤器检测“假”回调URI并使用该信号重新获得控制权。重建代理服务器的回调URI并使用Java / HTTP执行请求。
(代理服务器::回调URI)访问令牌的Exchange授权令牌,然后像以前一样将其存储以供将来调用
对OAuth提供程序进行API调用,并将响应文档返回到移动Web应用程序
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.
1)忘记代理服务器并直接从移动Web应用程序执行所有操作。这里最大的安全漏洞就是你需要在你的OAuth消费者密钥中“烘焙”并秘密进入你的应用程序。如果攻击者反编译您的代码并搜索这些字符串,对于具有逆向工程经验的人来说,这是一个相当简单的操作,它们会对您的应用程序和用户造成严重破坏。
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.
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
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:
仅供参考,虽然它不使用代理服务器,但以下示例说明了我将上述用于将浏览器会话注入您的移动应用OAuth交互并拦截回调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).
所以你看它看起来很丑陋,我甚至没有为用户创建和管理你自己的用户ID而烦恼,这样你就可以正确查找存储在代理Web服务器上的访问权限(包括一个PIN或访问代码的混乱,供用户管理)。
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:
有趣的注意事项:在对Android Web浏览器会话安全性进行一些研究时,我很高兴地发现您不能访问当前的网页HTML。如果您可以访问它,那么恶意的Android编码器可以轻松地嗅出用户的登录名和密码,从而完全破坏OAuth的目的和意图。我很沮丧地发现可能有办法通过CacheManager对象获取HTML。奇怪的是,根据Android文档,该对象现已被弃用并计划删除,因此希望这意味着Google发现了(潜在的)安全漏洞,并正在采取措施在即将推出的版本中将其删除:
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.
最后,我想听听那些在创建OAuth应用程序时遇到同样问题的人的想法。
-- roschler
1 个解决方案
#1
1
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.
Janrain发布了一个库,它提供了一些UI粘合剂和一个代理后端登录系统;它支持一堆流行的OAuth身份提供商(例如Google / FB)。在登录流程结束时,您将从设备获得HTTPS POST,为您提供可交换用户标识符和其他信息的令牌,以及用于向设备返回访问令牌的通道。
http://www.janrain.com/products/engage/mobile
https://github.com/janrain/engage.android
Disclosure: I work at Janrain, on this library.
披露:我在Janrain工作,在这个图书馆工作。
#1
1
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.
Janrain发布了一个库,它提供了一些UI粘合剂和一个代理后端登录系统;它支持一堆流行的OAuth身份提供商(例如Google / FB)。在登录流程结束时,您将从设备获得HTTPS POST,为您提供可交换用户标识符和其他信息的令牌,以及用于向设备返回访问令牌的通道。
http://www.janrain.com/products/engage/mobile
https://github.com/janrain/engage.android
Disclosure: I work at Janrain, on this library.
披露:我在Janrain工作,在这个图书馆工作。