什么 OpenID Connect 授权流程来验证移动应用程序用户?
Posted
技术标签:
【中文标题】什么 OpenID Connect 授权流程来验证移动应用程序用户?【英文标题】:What OpenID Connect authorization flow to authenticate mobile app users? 【发布时间】:2015-03-26 09:51:17 【问题描述】:我正在构建一个与 RESTful API 交互的跨平台移动应用程序,我想使用 OpenID Connect 对我的用户进行身份验证。我将构建自己的 OpenID Connect 提供程序服务器。
OpenID.net claims 那:
OpenID Connect 允许所有类型的客户端(包括基于浏览器的 javascript 和本机移动应用程序)启动登录流程并接收有关登录用户身份的可验证断言。
但是,我找不到任何说明如何为移动应用客户端实际进行身份验证的文档。
This StackExchange answer 明确表示 OpenID Connect 不支持“基于资源所有者密码的授权”流程或“客户端凭据”流程。
只剩下“授权代码”流程(通常由服务器端应用程序使用)和“隐式授权”流程(通常由客户端应用程序使用)。这两者似乎都依赖于将用户重定向到提供者的授权端点,并让提供者重定向回客户端 URL。我不明白这如何适用于移动应用程序。
谁能给我解释一下(或者更好的是,给我一个教程或一些示例代码)来解释如何做到这一点?
更新
澄清一下:OpenID Connect 依赖于客户端将用户重定向到授权端点,然后提供者将用户重定向回到客户端。如果客户端不是 Web 应用程序,这将如何工作?
【问题讨论】:
如果 OpenID Connect 只是一个 OAuth 2.0 扩展,我猜想授权服务器仍然可以将资源所有者凭据授予作为 OAuth 2.0 规范的一部分来实现?一旦移动应用程序具有访问令牌,我在 OIDC 规范中看不到任何禁止应用程序通过 UserInfo 端点访问用户信息的内容。 见***.com/questions/24047047/… 此处提供了包含最新最佳实践的完整教程medium.com/klaxit-techblog/… 【参考方案1】:移动应用(至少在 ios 和 android 上)可以注册自定义 URL 方案,以便来自浏览器的重定向可以将用户连同一些查询参数一起发送回您的应用。
因此,您可以在本机移动应用程序中使用这些流,但这需要将用户发送到 Web 浏览器(外部浏览器应用程序或内置于您的应用程序中的 Web 视图),以便他们通过 OP 进行身份验证.
完整的文章介绍了如何在本机移动应用程序上安全地实施“授权码授予”流程:Building an OpenID Connect flow for mobile。它基于最新的IETF OAuth 2.0 Security Best Current Practice。
另请注意,“隐式授予”流的使用现在是highly discouraged。
【讨论】:
谢谢詹姆斯。我认为你是对的,就我而言,因为它是我自己的应用程序,OIDC 不是适合这项工作的工具。 不要忘记“受信任/自己的”应用程序中使用的第 3 方框架可能会访问用户输入的凭据。使用 SFSafariViewController 方法,为用户提供便利(即留在应用程序内)和安全性(应用程序看不到输入的凭据),如果有多个应用程序/站点,它还提供 SSO。【参考方案2】:我认为 OpenID Connect 规范中的 混合流 可能是您想要使用的。 OpenID Connect Core Spec.
这确实依赖于配置返回 URI,但正如 James 所说,您将使用自定义 URI 方案来使移动操作系统能够在登录到您自己的应用程序后重定向。然后,您的应用将拥有一个访问代码,可用于根据需要获取访问令牌(假设您使用 Oauth2 来保护移动应用使用的后端 API 服务)。
存在允许恶意应用劫持您的 URI 方案并获取令牌的漏洞,有一个规范草案可以克服 Proof Key for Code Exchange by OAuth Public Clients,值得考虑实施。
【讨论】:
根据我的理解混合流需要客户端有一个客户端密钥。这在最终用户控制运行软件的设备(例如移动应用程序、桌面应用程序、单页应用程序 JavaScript 应用程序)的情况下是不可行的,在这种情况下,仅授权码授予对移动应用程序就足够了(可以安全地存储refresh_token
)或隐式流(用于无法信任存储会话之间任何安全状态的单页应用程序)。
隐式流确实应该始终用于基于浏览器的 OpenID 连接。我所指的 PKCE 允许应用程序拥有一个秘密,以防止其他应用程序劫持响应。当然,对移动应用使用隐式流是完全可能的。【参考方案3】:
如上所述,使用应用方案 URL 是正确的答案。我想补充说明一下,因为上面的一些回复包括指向一篇文章的链接,该文章对合规的 SSO 设计做出了不完整的断言,并使其对于简单的 SSO 用例来说变得不必要地复杂。我认为 google 的模型是安全的,因此我可能会按照他们的工作方式模拟 OIDC 与本土 IDP 的交互。
https://medium.com/klaxit-techblog/openid-connect-for-mobile-apps-fcce3ec3472 上面链接的本文中的设计,如文章图表所示,不适用于 google 在 Android 上的 oAuth/OIDC 实现。这有两个原因:
-
Google 不会为键入“Android”的 oAuth 客户端提供任何 client_secret
假设我切换到“Web”应用程序,该应用程序确实有一个秘密:对于键入“Web”的 oAuth 客户端,Google 不允许使用除“http”或“https”之外的 redirect_uri
相反,google 官方建议让典型的移动流程(您也应该使用 PKCE)在客户端上放置一个 ID 令牌,然后客户端可以将其交换为与应用服务器的会话: https://developers.google.com/identity/sign-in/android/backend-auth
这是安全的,因为您的 IDP 应该使用私钥签署 JWT ID 令牌,以便它可以由您系统的应用程序/服务验证,并用于断言适用于特定 OIDC 客户和受众的已验证(未过期)身份。 ** 不要将 ID 令牌作为授权传递给每个请求,而是与您的后端交换一次,以获得由您的应用程序管理的安全会话上下文。
【讨论】:
【参考方案4】:在 github 上查看MITREid project:
MITREid 连接
此项目包含一个 OpenID Connect 参考实现 Spring平台上的Java,包括一个正常运行的服务器库, 可部署的服务器包、客户端 (RP) 库和通用实用程序 图书馆。服务器可用作 OpenID Connect 身份 提供程序以及通用 OAuth 2.0 授权服务器。
【讨论】:
我不确定这是否有帮助。客户端库是为 Web 应用程序设计的 (c.f. github.com/mitreid-connect/simple-web-app)。我的问题是关于您的客户端何时不是网络应用程序。以上是关于什么 OpenID Connect 授权流程来验证移动应用程序用户?的主要内容,如果未能解决你的问题,请参考以下文章
OpenID Connect Core 1.0使用授权码流验证(上)
OpenID Connect Core 1.0使用授权码流验证(下)