我们的团队目前分为在 Angular 端或服务器端进行 Oauth2 身份验证(使用第三方身份提供商)(我们可能在服务器端有一个中间层,例如**代理层**,它执行身份验证等操作)然后将调用转发到带有不记名令牌的实际 REST API)。
根据我在网络上的研究,看起来最好在服务器端而不是前端**生成和存储访问令牌,主要是为了安全目的。
方法1 我也更倾向于服务器端 Oauth2 身份验证,我们在代理服务器端生成访问令牌,并将其映射到尝试成功登录的给定用户 ID,作为某些令牌存储机制的一部分。 (或者) Spring 本身有很多内置的东西,其中用户会话已经映射到访问令牌等,作为某些内存会话存储的一部分,并无缝处理访问令牌过期。我们可能会首先使用它。
**问题**:- 这种方法是否存在任何安全漏洞,我们从服务器传递到客户端/浏览器的唯一内容是一个 cookie,其中只有用户 ID 信息,并且在后续来回调用中使用它。然后,代理服务器获取该用户相应的访问令牌,并发送附加到请求的访问令牌的 api 调用。
方法2:
在角度/前端完成所有 Oauth2 身份验证。随着 PKCE 的引入,我们可以在授权码授权类型之上使用它。 一旦从身份提供者发送访问令牌,我们计划将其存储在前端的 cookie 中,并将其附加到后端服务器的后续调用。 与方法 1 相比,这实现起来不太复杂。 并且有一种无状态的方法,我们并不真正热衷于此,也不是必须的。
问题:-这种方法会存在任何安全漏洞吗? 我知道如果我们计划将访问令牌存储为浏览器/系统端本地存储的一部分,则可能会受到 CSS 攻击。但是,如果我们不将访问令牌存储在任何地方,而只是将其作为 cookie 的一部分发送到后端服务器,根据我的阅读,我们最终可能会遭受 CSRF 攻击。 我仍然需要获得更多有关 CSRF 攻击的知识,但方法 1 不也是这样吗?
根据 Spring Security 团队最新建议,您应该在服务器上使用“机密”OAuth2 客户端,而不是在浏览器中使用“公共”客户端。
我使用的一个选项是在 Angular 应用程序和 Spring 资源服务器之间使用
spring-cloud-gateway
和 spring-boot-starter-oauth2-client
过滤器配置 TokenRelay=
。我为此写了一个教程there(你可以尝试一下here)。