请耐心等待我解释我的问题以及我找到的解决方案/指南。
描述:在我的公司,我们有一个产品有多个模块。每个模块都是独立的后端和前端。我们有JavaEE/JakartaEE,JAX-RS作为后端堆栈,React作为前端堆栈。到目前为止,我们通过会话使用JavaEE Security来使用基本身份验证,但由于产品正在发展,我们需要移动客户端并允许第三方访问数据,我们决定将OAuth2/OpenID Connect集成到我们的应用程序中。
由于有多种实现提供OAuth2功能,我们目前正在研究一些可用的选项。(例如Keycloft和ORY Hydra)。我们将选择的决策取决于我们想做多少工作来改变应用程序的现有结构——我们如何处理数据库中的用户。但无论我们选择哪种实施方式,我们都会面临类似的问题。
问题
-
react应用程序如何处理登录过程和令牌存储?
每个文档都说:如果用户没有登录,他将被重定向到登录页面。登录并同意后,他将被重定向回应用程序(显然是在完成oauth2工作流后),并使用资源服务器的访问/ID令牌和/或刷新访问/ID代币的刷新令牌
现在我不清楚的是:
-
由于这是我们自己的React应用程序,我们不想显示同意屏幕,就像在微软/谷歌等公司的应用程序中一样,你看不到任何同意屏幕。我想这是可能的,可以在请求本身设置一个值,或者根据客户端id跳过同意屏幕,但我只想确保。
-
接下来是访问和刷新令牌的存储位置?接入令牌应作为承载令牌随每个请求一起发送。因此,它可以存储在本地存储中,因为它们的寿命很短,但刷新令牌应该安全存储。就像在安全的http cookie中一样?。如果是这样的话,那么服务器必须设置它。如果这是正确的,流会是这样的吗?
Our React App (Not logged In)
->Login Page (Another React Page)
->User Enters Credentials
->Java Backend
->Authenticates the user
->Initiate the OAuth2 process
->Get the Access and Refresh Tokens
->Set them as secure Cookies
->Return the authenticated response to frontend with the cookies
->Login Page redirects to the previous page
->User continues with the app
这感觉不正确。PKCE在这种情况下有什么帮助?
-
-
假设我上面写的是正确的,当用户从我们自己的应用程序或第三方应用程序登录时,我需要不同的登录流。然而,这可以通过检查客户端ID或禁用第三方客户端的密码流来确定。
-
这同样适用于刷新令牌流。因为对于我自己的应用程序,我必须设置cookie,对于第三方,这必须直接来自OAuth服务器
我阅读/研究过的资源:
https://gist.github.com/mziwisky/10079157
OAuth是如何工作的?
编辑:添加更多链接我已经阅读
隐式授予的目的是什么
会话管理的最佳实践
RESTful身份验证
当然还有各种各样的文章和例子,从钥匙斗篷和九头蛇也。
我目前正在尝试Keycloft和ORY Hydra,找出哪种更适合我们的需求。
提前感谢大家!
- 您不必显示同意屏幕。以下是React应用程序使用授权代码授予进行身份验证的示例:https://fusionauth.io/blog/2020/03/10/securely-implement-oauth-in-react(完全公开,这在我雇主的网站上,但可以与任何符合OAuth2的身份服务器一起使用)
简单的答案是,最好避免隐式授予,并将访问和刷新令牌存储在一些中间件中,而不是浏览器中。链接中的示例使用100行express服务器,并将这些令牌存储在会话中。
我写了一些关于PKCE的文章。摘录:
代码交换的证明密钥(PKCE)RFC于2015年发布,它扩展了授权代码授予,以在部分授权流通过非TLS连接时免受攻击。例如,在本机应用程序的组件之间。如果TLS存在漏洞,或者路由器固件已被破坏,并且正在欺骗DNS或从TLS降级为HTTP,也可能发生此攻击。PKCE要求向OAuth服务器发送额外的一次性代码。这用于验证请求是否未被拦截或修改。
- 以下是您拥有的各种OAuth选项的明细(同样,这在我雇主的网站上,但可以与任何符合OAuth2的身份服务器一起使用):https://fusionauth.io/learn/expert-advice/authentication/login-authentication-workflows您可以为不同的客户端允许不同的流。例如,您可以为第三方使用授权代码授予,为自己的应用程序使用资源所有者密码凭据授予(本质上是用户名和密码)
我不确定我是否回答了你的所有问题,但我希望其中一些问题会有所帮助。
应参考OAuth 2.0安全性最佳当前实践。尽管它仍然是一个";互联网草案";它是成熟的,并且已经由几个供应商实现。
通常,无论使用承载令牌还是JWT,都建议使用带有PKCE流的OAuth 2.0授权代码。
您还应该考虑阅读有关WebAuthn(没有密码的地方)