【问题标题】:Integrate oauth2 with native (iOS/Android) mobile application将 oauth2 与本机 (iOS/Android) 移动应用程序集成
【发布时间】:2013-04-18 05:28:01
【问题描述】:

我需要将 OAuth2 集成到 iOS 和 Android 原生应用程序中。我一直在研究 OAuth2 和移动应用程序并找到了这个文档 - Google APIs - Using OAuth 2.0 for Installed Applications

上述文档基本上详细介绍了如何在移动应用程序中使用 Goolge OAuth 2.0 端点。

文件是这样写的-

  1. 注册应用程序时,您指定该应用程序是已安装的应用程序。这会导致 redirect_uri 参数的值不同。
  2. 注册时获取的client_id 和client_secret 嵌入到您的应用程序的源代码中。在这种情况下,client_secret 显然不被视为机密。
  3. 授权码可以在浏览器的标题栏中返回到您的应用程序,也可以返回到查询字符串中的http://localhost 端口。

假设用户在其智能手机上安装了 2 个应用程序。

App1 - 使用 Google OAuth2.0 端点的合法应用

App2 - 恶意应用

我不确定的是,上述在原生移动应用程序中集成/使用 OAuth2.0 端点的技术是否不安全,或者我是否遗漏了什么。这是我的问题 -


  • redirect_uri 可以是http://localhost URL,并且可以包含任何端口号。端口号不是初始 API 配置的一部分,因此它可以是任何有效的端口号。此外,client_id(无论如何都不应该是秘密)和 client_secret 并不是真正的秘密,因为它们嵌入在移动应用程序源代码中。

使用上述条件,是不是有以下可能-

  1. 用户启动 App2
  2. App2 将用户重定向到 Google OAuth2.0 端点,但在请求中,App2 包含 App1 的 client_id 并包含 App2 正在侦听的本地端口号。
  3. 当用户被重定向并通过 Google OAuth2.0 端点进行身份验证时,Google 会向用户指示“App1(合法应用程序)要求代表用户访问 Google API 的/数据”,这似乎是网络钓鱼攻击,因为用户可能会点击是,认为是 App1 正在请求访问。
  4. Google OAuth2.0 将向 App2 发出授权码,然后 App2 可以发出下一个请求,包括 App1 的 client_id 和 client_secret 并获取 access_token 和 refresh_token 并继续从 Google 访问用户数据。

  • redirect_uri 也可以是 - urn:ietf:wg:oauth:2.0:oob,这意味着 -

该值向 Google 授权服务器发出信号,即授权代码应在浏览器的标题栏中返回。当客户端在没有重要客户端配置的情况下无法侦听 HTTP 端口时,这很有用。 Windows 应用程序具有此特性。

使用此值时,您的应用程序可以感知到页面已加载并且 HTML 页面的标题包含授权代码。如果您想确保用户永远不会看到包含授权代码的页面,则由您的应用程序关闭浏览器窗口。执行此操作的机制因平台而异。

上面的意思是授权码在浏览器窗口的标题中返回。

我的问题是 - App2 是否也可以感知页面已加载并捕获授权代码,然后使用它(在 App1 之前)连同 client_id 和 client_secret 来获取 access_token 和 refresh_token。浏览器实例是全局的并且任何应用程序都可以监控它并且上述攻击场景是有效的,还是浏览器实例以某种方式特定于应用程序以便只有 App1 可以感知/监控更改?


我的理解正确还是我遗漏了什么?我是否错过了缓解上述威胁的任何缓解措施?或者鉴于我们在移动操作系统平台上,上述风险是否有效但可以接受?

在移动应用程序中使用 OAuth2.0 的安全方式是什么? - 在浏览器页面中显示授权码并让用户在应用程序中手动输入?在这种情况下,浏览器实例是私有的,以便另一个应用程序无法监控它并在用户将授权码键入合法的api之前获取它本身?

感谢任何帮助

感谢和问候,

【问题讨论】:

  • 请问您为什么假设 app2 可以访问 app1 的 client_secret?没有 client_secret app2 不能对授权码做任何事情。我并不是说它不可能,但我认为这不是微不足道的。
  • @anfab - 我在考虑有人下载该应用程序的可能性。二进制文件并对其进行反编译或打印出应用程序中的硬编码字符串。泄露客户秘密...

标签: google-api oauth-2.0 security google-oauth


【解决方案1】:

不是对这个问题的直接回答,而是针对像我一样来到这里并得到过时回复的人。最好从这里开始:Google have published 他们的 OAuth Java 库和 Scribe 已准备好 Java。

【讨论】:

    【解决方案2】:

    根据我的经验,我发现实际上支持以干净方式检索授权码的库很少。

    在大多数移动平台上,您可以“收听”重定向 URL(是 http 或一些自定义方案)

    例如,在 Android 上,可以轻松创建一个活动来检索访问令牌(基于它通过重定向 URL 接收到的授权代码。

        <activity android:name=".OAuthAccessTokenActivity" android:launchMode="singleTask">>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="http" android:host="localhost"  />
            </intent-filter>
        </activity>   
    

    在这种情况下

    http://localhost
    

    在像 Android 这样的移动平台上,这似乎是合乎逻辑的事情。

    在 iOS 上也可以这样做,但如果我没记错的话,iOS 的 Google OAuth 库使用页面标题方法。

    从技术上讲,这两种流程之间没有区别。唯一的区别是重定向 URL 的语法,导致授权码的位置不同。

    从安全的角度来看,如果没有 OAuth2 客户端密码,仅授权码是毫无价值的。

    让用户输入授权码是我在 Oauth2 流程中不习惯看到的,但这是可能的。如果怀疑它会增加任何安全性。恕我直言,它只会让用户感到沮丧。

    这并不意味着检索和处理授权代码有不同的方式(通过使用 localhost 或自定义 URI 方案的重定向自动捕获代码,或手动交付)

    【讨论】:

    • 客户端的秘密虽然不是真正的秘密(正如谷歌文档指出的那样),因为有人可以反编译应用程序并获得相同的知识......
    • 我问过一个关于移动应用程序中客户端机密的类似问题 (stackoverflow.com/questions/4419915/…)。必须假设获取客户端机密是一回事,但随后冒充您的应用程序并使用该客户端机密来欺骗用户认为您的应用程序要求再次访问他的数据是另一回事。但我同意将其保留在您的应用中并不是 100% 严格的。代理到网络服务器是另一个间接级别,但仍然不是 100% 紧密。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 2016-01-29
    • 2012-09-19
    相关资源
    最近更新 更多