我正在尝试使用OAuth 2.0在移动应用程序的Web API中实现委派授权 . 根据规范,隐式授权流程不支持刷新令牌,这意味着一旦授予访问令牌特定时间段,用户必须在令牌过期或撤销后再次向应用程序授予权限 . 我想这对于在浏览器上运行的一些javascript代码是一个很好的场景,因为它在规范中提到了 . 我正在尝试最小化用户必须向应用授予权限以获取令牌的时间,因此看起来授权代码流是一个很好的选择,因为它支持刷新令牌 . 但是,这种流程似乎很大程度上依赖于Web浏览器来执行重定向 . 我想知道如果使用嵌入式Web浏览器,这个流程对于移动应用程序是否仍然是一个不错的选择 . 或者我应该采用隐式流程?
5 回答
不幸的是,我不认为这个问题有明确的答案 . 但是,我已经确定了以下选项:
如果可以询问用户他/她的凭据,那么请使用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
)通知授权 endpoints 以显示授权代码,而不是重定向回客户端应用程序 . 用户可以手动复制此代码,或者应用程序可以尝试从HTML文档 Headers 中获取它 .在设备上使用
localhost
服务器(端口管理可能不容易) .使用自定义URI方案(例如
myapp://...
),当解除引用时触发已注册的"handler"(详细信息取决于移动平台) .如果可用,请使用特殊的"web view"(例如Windows 8上的WebAuthenticationBroker)来控制和访问HTTP重定向响应 .
希望这可以帮助
佩德罗
在移动应用程序中使用webview应该是在Android平台上实施OAuth2.0协议的经济实惠的方式 .
至于redirect_uri字段,我认为
http://localhost
是一个不错的选择,你不必在你的应用程序中移植HTTP服务器,因为你可以在WebViewClient
类中覆盖onPageStarted
函数的实现并在你之后停止从http://localhost
加载网页检查url
参数 .TL;DR: 使用授权码授予PKCE
1. Implicit Grant Type
隐式授权类型在移动应用程序中非常流行 . 但它不应该像这样使用 . 重定向存在安全问题 . Justin Richer states:
并且事实上,它不会让您刷新访问令牌,更好地避免它 .
2. Authorization Code Grant Type
授权代码授权需要客户端密钥 . 但是,您不应将敏感信息存储在移动应用的源代码中 . 人们可以提取它们 . 要不公开客户端密钥,您必须将服务器作为中间人运行为Facebook writes:
不是一个理想的解决方案,但有一种新的,更好的方式在移动设备上进行OAuth:代码交换的证明密钥
3. Authorization Code Grant Type with PKCE (Proof Key for Code Exchange)
出于这些限制,我们创建了一种新技术,可让您在没有客户机密的情况下使用授权代码 . 您可以阅读完整的RFC 7636或this short introduction .
来自https://oauth.net/2/pkce/
用于身份验证的最流畅的用户体验,以及最容易实现的是在您的应用中嵌入webview . 处理webview从身份验证点接收的响应并检测错误(用户取消)或批准(以及从URL查询参数中提取令牌) . 而且我认为你可以在所有平台上实现这一点 . 我已成功完成以下工作:ios,android,mac,windows store 8.1应用程序,windows phone 8.1应用程序 . 我为以下服务做了这个:dropbox,google drive,onedrive,box,basecamp . 对于非Windows平台,我使用的是Xamarin,据说它不会暴露整个平台特定的API,但它确实暴露了足以使这成为可能 . 所以它是一个非常易于访问的解决方案,即使从跨平台的角度来看,您也不必担心身份验证表单的ui .
澄清:移动应用程序=本机应用程序
正如其他评论和在线的一些消息来源所述,隐式似乎非常适合移动应用程序,但最好的解决方案并不总是明确的(事实上,由于下面讨论的原因,不推荐隐含) .
Native App OAuth2 Best Practises
无论您选择哪种方法(需要考虑一些权衡),您应该注意使用OAuth2的本地应用程序中概述的最佳实践:https://tools.ietf.org/html/rfc8252
请考虑以下选项
Implicit
我应该使用隐含的吗?
引用第8.2节https://tools.ietf.org/html/rfc8252#section-8.2
Authorization Code
如果您使用授权代码,那么一种方法是通过您自己的Web服务器组件进行代理,该组件使用客户端密钥丰富令牌请求,以避免将其存储在设备上的分布式应用程序上 .
摘录如下:https://dev.fitbit.com/docs/oauth2/
Conclusion
在对您的入围方法进行适当的风险评估并更好地理解其影响之后,最终决定应考虑您所期望的用户体验以及您对风险的偏好 .
一个很好的阅读在这里https://auth0.com/blog/oauth-2-best-practices-for-native-apps/
另一个是https://www.oauth.com/oauth2-servers/oauth-native-apps/,其中说明了这一点
PKCE Consideration
您还应该考虑这里描述的PKCE https://www.oauth.com/oauth2-servers/pkce/
具体来说,如果您还要实施授权服务器,那么https://www.oauth.com/oauth2-servers/oauth-native-apps/checklist-server-support-native-apps/表明您应该这样做
允许客户为其重定向URL注册自定义URL方案 .
支持环回IP重定向具有任意端口号的URL,以支持桌面应用 .
不要假设本机应用程序可以保守秘密 . 要求所有应用程序声明它们是公开的还是保密的,并且只向机密应用程序发出客户机密 .
支持PKCE扩展,并要求公共客户端使用它 .
尝试检测授权界面何时嵌入本机应用程序的Web视图,而不是在系统浏览器中启动,并拒绝这些请求 .
Web Views Consideration
在野外有很多使用Web视图的例子,即嵌入式用户代理,但应该避免这种方法(特别是当应用程序不是第一方时),并且在某些情况下可能会导致您被禁止使用API作为摘录以下来自here演示
为进一步澄清,以下是上文提供的最佳实践链接的先前草案的this section引用
这里也提出了一些有趣的观点:https://security.stackexchange.com/questions/179756/why-are-developers-using-embedded-user-agents-for-3rd-party-auth-what-are-the-a