适用于移动应用的OAuth 2.0流程是什么?

时间:2013-07-02 14:04:26

标签: security mobile oauth-2.0

我正在尝试使用OAuth 2.0在移动应用的Web API中实现委派授权。根据规范,隐式授权流程不支持刷新令牌,这意味着一旦授予访问令牌一段特定时间,用户必须在令牌过期或撤销后再次向应用程序授予权限。我想这是在浏览器上运行的一些javascript代码的一个很好的场景,正如规范中提到的那样。我试图最小化用户必须向应用授予权限以获取令牌的时间,因此看起来授权代码流是一个很好的选择,因为它支持刷新令牌。但是,此流程似乎很大程度上依赖于Web浏览器来执行重定向。我想知道如果使用嵌入式Web浏览器,这个流程对于移动应用程序仍然是一个不错的选择。或者我应该采用隐式流程?

5 个答案:

答案 0 :(得分:68)

澄清:移动应用=原生应用

正如其他评论和在线的一些消息来源所述,隐式似乎非常适合移动应用程序,但最好的解决方案并不总是明确的(事实上,由于下面讨论的原因,不推荐隐含)。

Native App OAuth2最佳做法

无论您选择哪种方法(需要考虑一些权衡),您都应该注意使用OAuth2的本地应用程序中列出的最佳做法:https://tools.ietf.org/html/rfc8252

考虑以下选项

<强>隐

我应该使用隐式吗?

引用第8.2节https://tools.ietf.org/html/rfc8252#section-8.2

  

OAuth 2.0隐式授权流程(在OAuth 2.0 [RFC6749]的第4.2节中定义)通常适用于在浏览器中执行授权请求并通过基于URI的应用间通信接收授权响应的做法。登记/>   但是,由于PKCE [RFC7636](第8.1节中要求)无法保护隐式流,不推荐使用隐式流与本机应用

     

通过隐式流授予的访问令牌也无法在没有用户交互的情况下刷新,从而使授权代码授予流程 -   可以发出刷新令牌 - 对于需要刷新访问令牌的本机应用程序授权,更实用的选项。

授权码

如果您使用授权码,那么一种方法是通过您自己的Web服务器组件进行代理,该组件使用客户端密钥丰富令牌请求,以避免将其存储在设备上的分布式应用程序上。

摘录如下:https://dev.fitbit.com/docs/oauth2/

  

建议应用程序代码授予流程   有一个网络服务。此流程需要服务器到服务器的通信   使用应用程序的客户端密钥。

     

注意:切勿将您的客户端置于分布式代码中,例如应用程序   通过应用商店或客户端JavaScript下载。

     

没有Web服务的应用程序应使用Implicit   授予流量。

<强>结论

在对您的入围方法进行适当的风险评估并更好地理解其影响后,最终决定应考虑您所需的用户体验,以及您对风险的偏好。

这里有很好的阅读https://auth0.com/blog/oauth-2-best-practices-for-native-apps/

另一个是https://www.oauth.com/oauth2-servers/oauth-native-apps/,表示

  

目前的行业最佳做法是使用授权流程   同时省略客户端密钥,并使用外部用户代理   完成流程。外部用户代理通常是设备的代理   本机浏览器,(与本机应用程序具有单独的安全域)   这样应用程序就无法访问cookie存储或检查或修改   浏览器中的页面内容。

PKCE考虑事项

您还应该考虑这里描述的PKCE https://www.oauth.com/oauth2-servers/pkce/

具体来说,如果您还要实施授权服务器,则https://www.oauth.com/oauth2-servers/oauth-native-apps/checklist-server-support-native-apps/表明您应该

  • 允许客户为其重定向网址注册自定义网址方案。
  • 支持环回IP重定向具有任意端口号的URL,以支持桌面应用。
  • 不要假设原生应用可以保守秘密。要求所有应用程序声明它们是公开的还是保密的,并且只向机密应用程序发出客户机密。
  • 支持PKCE扩展,并要求公共客户端使用它。
  • 尝试检测授权界面何时嵌入本机应用程序的Web视图,而不是在系统浏览器中启动,并拒绝这些请求。

网络视图考虑

有许多使用Web视图的例子,即嵌入式用户代理,但应该避免这种方法(特别是当应用程序不是第一方时),并且在某些情况下可能会导致您被禁止使用API正如here下面的摘录所示

  

任何嵌入OAuth 2.0身份验证页面的尝试都将导致   您的应用程序被禁止使用Fitbit API。

     

出于安全考虑,必须使用OAuth 2.0授权页面   以专用的浏览器视图显示。 Fitbit用户只能确认   他们正在使用真正的Fitbit.com网站进行身份验证   浏览器提供的工具,例如URL栏和传输   层安全性(TLS)证书信息。

     

对于本机应用程序,这意味着必须打开授权页面   在默认浏览器中。本机应用程序可以使用自定义URL方案   作为重定向URI,用户将用户从浏览器重定向到   申请请求许可。

     

iOS应用程序可能使用SFSafariViewController类而不是   应用切换到Safari。使用WKWebView或UIWebView类是   禁止的。

     

Android应用可能会使用Chrome自定义标签而不是应用   切换到默认浏览器。禁止使用WebView。

为进一步澄清,以下是上文提供的最佳做法链接的先前草案this section的引用

  

通常使用网络视图实现的嵌入式用户代理是一种   授权本机应用程序的替代方法。然而,他们   根据定义,第三方不安全使用。它们涉及用户   使用完整的登录凭据登录,只能拥有它们   缩小到不太强大的OAuth凭证。

     

即使被受信任的第一方应用程序,嵌入式用户代理使用也是如此   通过获得更强大的力量来违反最小特权原则   证书超出他们的需要,可能会增加攻击面。

     

在嵌入式用户代理的典型基于Web视图的实现中,   主机应用程序可以:记录表单中输入的每个击键   捕获用户名和密码;自动提交表格并绕过   用户同意;复制会话cookie并使用它们来执行   作为用户的经过身份验证的操作。

     

鼓励用户在没有嵌入式Web视图的情况下输入凭据   通常的地址栏和浏览器具有的其他身份功能   使用户无法知道他们是否正在登录   合法的网站,即使它们是,它训练他们没关系   输入凭据而不先验证网站。

     

除了安全问题,网络视图不共享   与其他应用程序或系统浏览器的身份验证状态,需要   用户登录每个授权请求并导致a   用户体验不佳。

     

由于上述原因,建议不要使用嵌入式用户代理,   除非受信任的第一方应用程序充当外部用户 -   其他应用的代理,或首先为多个应用提供单点登录   派对应用程序。

     

授权服务器应该考虑采取措施来检测和阻止   通过嵌入式用户代理登录,这些用户代理不是他们自己的,在哪里   可能的。

此处还提出了一些有趣的观点:https://security.stackexchange.com/questions/179756/why-are-developers-using-embedded-user-agents-for-3rd-party-auth-what-are-the-a

答案 1 :(得分:21)

不幸的是,我不认为这个问题有明确的答案。但是,我已经确定了以下选项:

  • 如果可以询问用户他/她的凭据,请使用Resource Owner Password Credentials。但是,由于某些原因,这可能是不可能的,即

    • 可用性或安全政策禁止直接在应用中插入密码
    • 身份验证过程在外部身份提供程序上委派,必须通过基于HTTP重定向的流程执行(例如OpenID,SAMLP或WS-Federation)
  • 如果需要使用基于浏览器的流程,请使用Authorization Code Flow。在这里,redirect_uri的定义是一项重大挑战,有以下几种选择:

    • 使用https://developers.google.com/accounts/docs/OAuth2InstalledApp中描述的技术,其中特殊redirect_uri(例如urn:ietf:wg:oauth:2.0:oob)表示授权端点显示授权代码,而不是重定向回客户端应用。用户可以手动复制此代码,或者应用程序可以尝试从HTML文档标题中获取它。
    • 在设备上使用localhost服务器(端口管理可能不容易)。
    • 使用自定义URI方案(例如myapp://...),当解除引用时触发已注册的“处理程序”(详细信息取决于移动平台)。
    • 如果可用,请使用特殊的“网络视图”,例如Windows 8上的WebAuthenticationBroker,以控制和访问HTTP重定向响应。

希望这有帮助

佩德罗

答案 2 :(得分:8)

TL; DR:使用授权码授予PKCE

<强> 1。隐含授权类型

隐式授权类型在移动应用中非常受欢迎。但它并不意味着像这样使用。重定向存在安全问题。 Justin Richer states

  

当您意识到与远程服务器不同时,问题就出现了   URL,没有可靠的方法来确保之间的绑定   给定重定向URI和特定的移动应用程序是值得尊敬的。任何   设备上的应用程序可以尝试将自身插入重定向   进程并使其提供重定向URI。猜猜:如果   您已经在本机应用程序中使用了隐式流,然后是您   只是向攻击者提供了访问令牌。没有恢复   那一点 - 他们有令牌,他们可以使用它。

与事实一起,它不允许您刷新访问令牌,更好地避免它。

<强> 2。授权代码授权类型

授权代码授权需要客户机密钥。但是,您不应将敏感信息存储在移动应用的源代码中。人们可以提取它们。要不公开客户端密钥,您必须将服务器作为中间人运行为Facebook writes

  

我们建议只能直接使用App Access Tokens   您的应用程序的服务器,以提供最佳的安全性。对于本地人   应用程序,我们建议应用程序与您自己的服务器进行通信   然后,服务器使用App向Facebook发出API请求   访问令牌。

不是理想的解决方案,但有更新的,更好的方式在移动设备上执行OAuth:代码交换的证明密钥

第3。使用PKCE的授权代码授权类型(代码交换的证明密钥)

出于这些限制,我们创建了一种新技术,可让您在没有客户机密的情况下使用授权代码。您可以阅读完整的RFC 7636this short introduction

  PKCE(RFC 7636)是一种保护不使用的公共客户的技术   客户的秘密。

     

它主要由本机和移动应用程序使用,但该技术可以   适用于任何公共客户。它需要额外的   授权服务器支持,因此仅支持   某些提供者。

来自https://oauth.net/2/pkce/

答案 3 :(得分:-3)

在移动应用程序中使用webview应该是在Android平台上实施OAuth2.0协议的经济实惠的方式。

对于redirect_uri字段,我认为http://localhost是一个不错的选择,您不必在应用程序中移植HTTP服务器,因为您可以覆盖onPageStarted函数的实现WebViewClient课程,并在您检查http://localhost参数后停止从url加载网页。

public void onPageStarted(final WebView webView, final String url,
        final Bitmap favicon) {}

答案 4 :(得分:-4)

用于身份验证的最流畅的用户体验,最容易实现的是在您的应用中嵌入webview。处理webview从身份验证点接收的响应并检测错误(用户取消)或批准(以及从URL查询参数中提取令牌)。 我认为你可以在所有平台上实现这一点。我已成功完成以下工作:ios,android,mac,windows store 8.1应用程序,windows phone 8.1应用程序。我为以下服务做了这个:dropbox,google drive,onedrive,box,basecamp。对于非Windows平台,我使用的是Xamarin,据说它不会暴露整个平台特定的API,但它确实暴露了足以使这成为可能。所以它是一个非常易于访问的解决方案,即使从跨平台的角度来看,您也不必担心身份验证表单的用户界面。