哪种OpenID Connect授权流程用于验证移动应用程序用户?

35
我正在构建一个跨平台移动应用程序,与RESTful API交互,并希望使用OpenID Connect对我的用户进行身份验证。我将构建自己的OpenID Connect提供者服务器。
OpenID.net声称:
OpenID Connect允许所有类型的客户端(包括基于浏览器的JavaScript和本机移动应用程序)启动登录流程并接收有关已登录用户身份的可验证声明。
然而,我找不到任何文件说明如何为移动应用程序客户端实际进行身份验证。
这个StackExchange答案明确表示OpenID Connect不支持“资源所有者密码授权”流或“客户端凭据”流。
这只留下了“授权码”流(通常由服务器端应用程序使用)和“隐式授权”流(通常由客户端应用程序使用)。这两者似乎都依赖于将用户重定向到提供商的授权终点,并要求提供商重定向回客户端URL。我不知道这如何适用于移动应用程序。

有人可以为我解释一下(或者最好是指向一个教程或示例代码),来说明如何做到这一点吗?

更新

澄清一下:OpenID Connect依赖于客户端将用户重定向到授权终结点,然后提供程序将用户重定向回客户端。 在客户端不是Web应用程序的情况下,这怎么可能实现?


如果OpenID Connect只是OAuth 2.0的扩展,我想资源所有者凭据授权仍然可以作为OAuth 2.0规范的一部分由授权服务器实现。一旦移动应用程序拥有访问令牌,我没有看到OIDC规范中有任何禁止应用程序通过UserInfo端点访问用户信息的内容。 - Michael Técourt
请参见https://dev59.com/PGAg5IYBdhLWcg3wBXKs,了解OpenID Connect是否支持资源所有者密码凭证授权。 - Michael Técourt
这里提供了最新的最佳实践,完整的教程:https://medium.com/klaxit-techblog/openid-connect-for-mobile-apps-fcce3ec3472 - ccyrille
4个回答

27

移动应用程序(至少在iOS和Android上)可以注册自定义URL方案,以便从浏览器进行重定向时,可以将用户与一些查询参数一起发送回您的应用程序。

因此,您可以在本机移动应用程序中使用这些流程,但需要将用户发送到Web浏览器(外部浏览器应用程序或内置于您的应用程序中的Web视图),以便他们进行OP认证。

有一篇完整的文章介绍如何在本机移动应用程序上安全实现“Authorization Code Grant”流程,可在此处找到:Building an OpenID Connect flow for mobile。它基于最新的IETF OAuth 2.0安全最佳当前做法

还请注意,现在强烈不建议使用“Implicit Grant”授权流程。highly discouraged


谢谢James。我觉得你是正确的,在我的情况下,由于这是我的应用程序,OIDC不是合适的工具。 - PGleeson
2
不要忘记,“受信任/自有”应用程序中使用的第三方框架可能会访问用户输入的凭据。使用SFSafariViewController方法,它为用户提供了便利(即在应用程序内部停留)和安全性(应用程序无法看到输入的凭据),并且如果存在多个应用程序/站点,则提供SSO。 - pawi

3
我认为你可能需要使用OpenID Connect规范中的混合流程(Hybrid flow)。参考OpenID Connect核心规范
这需要有一个已配置的返回URI,但正如James所说,您可以使用自定义URI方案来使移动操作系统在登录后重定向到您的应用程序。然后,您的应用程序将拥有访问代码,可以根据需要使用它来获取访问令牌(假设您正在使用Oauth2保护移动应用程序使用的后端API服务)。
存在一种漏洞,允许恶意应用程序劫持您的URI方案并获取令牌。有一份草案规范可以解决这个问题OAuth公共客户端代码交换的证明密钥,值得考虑实施。

根据我的理解,混合流程要求客户端拥有客户端密钥。在最终用户控制运行软件的设备(例如移动应用程序、桌面应用程序、单页应用程序JavaScript应用程序)的情况下,这实际上是不可行的,此时仅授权码授予对于移动应用程序就足够了(可以安全地存储“刷新令牌”),或者使用隐式流程(对于不能信任存储任何安全状态的单页应用程序应用)。 - Dai
隐式流应该始终用于基于浏览器的OpenID连接。我所提到的PKCE允许应用程序拥有一个秘密,防止其他应用程序劫持响应。当然,对于移动应用程序来说,使用隐式流也是完全可行的。 - Alex White

0

如上所述,使用应用程序方案URL是正确的答案。我想添加额外的澄清,因为上面的一些回复包括链接到一篇文章,该文章对符合SSO设计的不完整断言进行了说明,并使简单的SSO用例变得不必要地复杂。我认为谷歌的模型很安全,因此我可能会按照他们的工作方式对自制IDP的OIDC交互进行建模。

https://medium.com/klaxit-techblog/openid-connect-for-mobile-apps-fcce3ec3472 如上链接的文章中的设计,如文章中的图表所示,在Android上无法使用谷歌的oAuth/OIDC实现。原因有两个:

  1. 谷歌不会为类型为“Android”的oAuth客户端提供任何client_secret
  2. 假设我切换到具有密钥的“Web”应用程序:谷歌不允许将重定向URI设置为oAuth客户端类型为“Web”之外的任何内容

谷歌官方建议您让典型的移动流程(同时也应该使用PKCE)在客户端上放置一个ID令牌,并将其交换为与应用服务器的会话:

https://developers.google.com/identity/sign-in/android/backend-auth

这是安全的,因为您的IDP应该使用私钥对JWT ID令牌进行签名,以便您系统的应用程序/服务可以验证并用于断言特定OIDC客户端和受众所预期的经过验证(未过期)身份。
**不要在每个请求上传递ID令牌作为授权,而是通过后端与您的应用程序管理的安全会话上下文进行一次交换。


-1

在Github上查看MITREid项目

MITREid Connect

该项目包含一个基于Spring平台的Java OpenID Connect参考实现,包括一个可运行的服务器库、可部署的服务器包、客户端(RP)库和通用工具库。该服务器可用作OpenID Connect身份提供者以及通用OAuth 2.0授权服务器。


我不确定这是否有帮助。客户端库是为 Web 应用程序设计的(参见 https://github.com/mitreid-connect/simple-web-app)。我的问题是,当您的客户端不是 Web 应用程序时该怎么办。 - PGleeson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接