java - Spring Security 未创建 CSRF 令牌
问题描述
我希望使用 Spring Security(版本 5.1.2)为我的 Angular 7 应用程序生成 CSRF 令牌。我的 SecurityConfig 文件中有以下内容:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
在我的控制器中使用以下 RequestMapping:
@RestController
@RequestMapping("/authentication")
public class AuthenticationController {
@GetMapping("/csrf")
public void getCsrfToken(){...}
@PostMapping("/register")
public RegisterOutputDTO register(@RequestBody UserDTO input){...}
}
我从各种来源收集到,在我第一次调用csrfTokenRepository
时会自动生成带有标头的 cookie (这就是目的),但我没有从服务器返回 cookie。因此,在我的下一个电话中,我收到了 403 响应。我可能会错过什么?XSRF-token
GET
/authentication/csrf
POST
解决方案
如对我的问题的评论所示,我找到了问题的答案。无法跨域发送 cookie。
我的前端部署在 上localhost:3000
,后端部署在 上localhost:9080
,显然它们被认为是不同的域。如果我去localhost:9080
(我得到一个白页,但这没关系)然后我去 Chrome 中的应用程序选项卡,我发现我正在寻找的 XSRF cookie 就像我一直期待的那样存储。cookie 可从GET
我从前端执行的调用中获得。问题是 cookie 需要可用,localhost:3000
以便 Angular 可以使用 cookie。
您可以通过多种方式在本地环境中解决此问题。
使用代理
您可以使用代理将某些 url 路径映射到后端。这是我采用的解决方案。
我使用 webpack 开发服务器运行我的 Angular 应用程序。Webpack 提供了一种将某些 url 代理到后端的简单方法。例如:
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 3000,
proxy: {
'/api': 'http://localhost:9080'
}
}
Angular 应用程序在localhost:3000
. 任何对localhost:3000/api/*
. 将转发到localhost:9080/api/*
。因此,在我的情况下,我不再GET
对 执行呼叫localhost:9080/api/authentication/csrf
,但我会呼叫localhost:3000/api/authentication/csrf
然后将其转发到我的后端。/api
(对于那些想知道的人,我在我的休息控制器中添加了路径。)
将两个应用程序部署在同一个端口上
使用frontend-maven-plugin您可以将前端构建到其 dist 文件夹,然后让 maven 将 dist 文件夹与后端一起打包以进行部署。我还没有尝试过,但是有各种资源表明这应该很容易通过 Spring boot 完成。因此,例如,前端和后端都可以使用localhost:9080
。
使用 Spring Profile 在本地禁用 csrf
您可以使用 Spring@Profile
注释为本地环境和其他环境(测试、验收、生产)创建不同的配置。可以简单地禁用 Csrf 以进行开发。我不喜欢这个选项,因为我喜欢尽可能保持 DEV 和其他环境相同。这也不是问题陈述的真正答案。
推荐阅读
- c# - 如何从服务器连接到onedrive,但将数据发送到前端(ui)?
- python - discord.py SyntaxError:“等待”外部函数
- python - Python - 查找多个值的首次出现的有效方法
- asp.net - asp.net webforms 类型名称冲突,当前页面出错
- jquery - 使用 Ajax 发送表单包含文件输入不会继续该功能
- spring-cloud-stream - 如何启用具有两个不同输入主题的函数路由
- javascript - 当有人说话时发送图像
- python - 具有多个输出的熊猫旋转数据框
- jquery - jquery在对话框中更改按钮文本颜色
- angular - 如何在 ng build --watch 上设置 HMR 并自动重新加载 URL?