security - 私有(private)应用程序的 OAuth2 流程和最佳实践

标签 security authentication oauth oauth-2.0 openid-connect

请耐心等待我解释我的问题和我找到的解决方案/指南。

描述:在我的公司,我们有一个产品有多个模块。每个模块都是其独立的后端和前端。我们有 JavaEE/JakartaEE,JAX-RS 作为我们的后端堆栈,React 作为我们的前端。到目前为止,我们一直在使用 Basic Authentication 通过 session 使用 JavaEE 安全性,但由于产品在不断发展,我们需要移动客户端并允许第三方访问数据,我们决定集成 OAuth2/OpenID Connect进入我们的应用程序。

由于有多种实现提供 OAuth2 功能,我们目前正在研究一些可用的选项。 (例如 KeycloakORY Hydra)。我们将选择的决定取决于我们想要做多少工作来改变应用程序的现有结构,我们如何处理数据库中的用户。但无论我们选择哪种实现方式,我们都会遇到类似的问题。

问题

  1. React 应用程序如何处理登录过程和 token 存储?

    每个文档都说:如果用户未登录,他/她将被重定向到登录页面。在登录并同意后,他被重定向回应用程序(显然在完成 oauth2 工作流之后),并使用资源服务器的访问/ID token 和/或刷新访问/ID token 的刷新 token 。

    下面是我不清楚的地方:

    • 由于这是我们自己的 React 应用,我们不想显示同意屏幕,就像在 Microsoft/Google 等应用中您看不到任何一样。我想这可以通过在请求本身中设置一个值,或跳过基于客户端 ID 的同意屏幕来实现,但我只是想确定一下。

    • 接下来是在哪里存储访问和刷新 token ?访问 token 应作为承载 token 随每个请求一起发送。所以它可以存储在本地存储中,因为它们是短暂的,但刷新 token 应该安全地存储。就像在安全的 http cookie 中一样?如果是这种情况,则服务器必须对其进行设置。如果这是正确的,流程会是这样吗?

      我们的 React 应用程序(未登录) --> 登录页面(另一个 React 页面) --> 用户输入凭据 --> Java 后端 --> 验证用户 --> 启动 OAuth2 进程 --> 获取访问和刷新 token --> 将它们设置为安全 Cookies --> 使用 cookies 将经过身份验证的响应返回给前端 --> 登录页面重定向到上一页 --> 用户继续使用该应用

      这感觉不对。在这种情况下,PKCE 将如何提供帮助?

  2. 假设我上面写的是正确的,当用户从我们自己的应用程序或第三方应用程序登录时,我将需要不同的登录流程。然而,这可以通过检查客户端 ID 或禁用第三方客户端的密码流来确定。

  3. 同样适用于刷新 token 流。因为对于我自己的应用程序,我必须设置 cookie,对于第三方,这必须直接来自 OAuth 服务器

我阅读/研究过的资源:

https://gist.github.com/mziwisky/10079157

How does OAuth work?

编辑:添加更多我已阅读的链接

What is the purpose of implicit grant

Best practices for session management

RESTful Authentication

当然还有来自 Keycloak 和 ORY Hydra 的各种著作和示例。

我目前正在尝试 Keycloak 和 ORY Hydra,看看哪个更符合我们的需求。

提前谢谢大家!

最佳答案

  1. 您不必显示同意屏幕。以下是使用授权码授予进行身份验证的 React 应用程序示例:https://fusionauth.io/blog/2020/03/10/securely-implement-oauth-in-react (完全公开,这是在我雇主的网站上,但可以与任何符合 OAuth2 标准的身份服务器一起使用)。

简短的回答是,您最好避免隐式授权,并将访问和刷新 token 存储在某些中间件中,而不是浏览器中。链接中的示例使用 100 行 express 服务器并将这些 token 存储在 session 中。

我写了一些关于 PKCE 的文章。摘录:

The Proof Key for Code Exchange (PKCE) RFC was published in 2015 and extends the Authorization Code grant to protect from an attack if part of the authorization flow happens over a non TLS connection. For example, between components of a native application. This attack could also happen if TLS has a vulnerability or if router firmware has been compromised and is spoofing DNS or downgrading from TLS to HTTP. PKCE requires an additional one-time code to be sent to the OAuth server. This is used to validate the request has not been intercepted or modified.

  1. 这是您拥有的各种 OAuth 选项的细目分类(同样,这是在我雇主的网站上,但可以与任何符合 OAuth2 的身份服务器一起使用):https://fusionauth.io/learn/expert-advice/authentication/login-authentication-workflows您可以为不同的客户端允许不同的流。例如,您可以为第三方使用授权代码授权,为您自己的应用程序使用资源所有者密码凭证授权(本质上是用户名和密码)。

我不确定我是否回答了您所有的问题,但我希望其中的一些内容对您有所帮助。

关于security - 私有(private)应用程序的 OAuth2 流程和最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61397514/

相关文章:

android - Android中sharedUserId的唯一性

javascript - Twitter API 调用仅使用 javascript 获取 OAuth 的 access_token

ruby-on-rails - yahoo、google、facebook策略在各种环境下如何使用和配置omniauth?

oauth - 控制台应用程序中的 Twitter OAuth

javascript - 我用我的 PHP 调用的数据文件被神秘地改变了。用户是否覆盖了它?

html - 如何使用基于浏览器的 S3 上传验证文件的内容?

javascript - 您可以阻止网站出现在浏览器的历史记录中吗?

java - 从 Java 应用程序以编程方式登录网站

PHP 登录/身份验证/ session /API/ token

security - 使用 cookie/ session 进行移动应用程序身份验证?