[在我解释我的问题和找到的解决方案/指南时,请多多包涵。
描述:在我的公司中,我们有一种产品具有多个模块。每个模块都是其各自的后端和前端。我们将JavaEE / JakartaEE和JAX-RS作为后端堆栈,将React作为前端。到目前为止,我们一直通过会话使用JavaEE Security来使用Basic Authentication,但是由于产品在不断发展,并且我们需要移动客户端并允许第三方访问数据,因此我们决定将OAuth2 / OpenID Connect集成到我们的应用程序中。
由于存在多个提供OAuth2功能的实现,因此我们目前正在研究一些可用的选项。 (例如Keycloak和ORY Hydra)。我们将选择的决定取决于我们要进行多少工作,以更改应用程序的现有结构,以及我们如何处理数据库中的用户。但是,无论我们选择哪种实现方式,我们都会遇到类似的问题。
问题
React应用程序如何处理登录过程和令牌存储?
每个文档都说:如果用户未登录,则他/他将被重定向到登录页面。登录并获得同意后,他将使用资源服务器的访问/ ID令牌和/或刷新令牌(用于刷新访问/ ID令牌)重定向到应用程序(显然完成了oauth2工作流之后)。
现在这是我不清楚的地方:
由于这是我们自己的React应用,因此我们不想显示同意屏幕,例如Microsoft / Google等应用中,您看不到任何内容。我想可以通过在请求本身中设置一个值,或者跳过基于客户端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
编辑:添加我已阅读的更多链接
What is the purpose of implicit grant
Best practices for session management
当然还有Keycloak和ORY Hydra的各种著作和示例。
我目前正在尝试Keycloak和ORY Hydra来确定更适合我们的需求。
谢谢大家!
简短的答案是,您最好避免隐式授予,并且将访问和刷新令牌存储在某些中间件(而不是浏览器)中。链接中的示例使用100行快速服务器并将这些令牌存储在会话中。
我写了一些关于PKCE的文章。摘录:
代码交换证明密钥(PKCE)RFC于2015年发布,并扩展了授权代码授予,以防止部分授权流通过非TLS连接发生攻击。例如,在本机应用程序的组件之间。如果TLS具有漏洞或路由器固件已受到攻击并欺骗DNS或从TLS降级为HTTP,则也可能发生此攻击。 PKCE需要将其他一次性代码发送到OAuth服务器。这用于验证请求未被拦截或修改。
我不确定我是否回答了您所有的问题,但我希望其中一些问题会有所帮助。
应咨询OAuth 2.0 Security Best Current Practice。即使它仍然是“ Internet草案”,它也已经成熟,并且已经由多个供应商实现了。
一般而言,无论使用不记名令牌还是JWT,都建议使用带有PKCE Flow的OAuth 2.0授权代码。
您还应该考虑阅读有关WebAuthn(没有密码的地方)