Java Spring Security未创建CSRF令牌
我希望使用Spring安全性(版本5.1.2)为我的Angular 7应用程序生成一个CSRF令牌。我的SecurityConfig文件中包含以下内容:Java Spring Security未创建CSRF令牌,java,angular,spring-security,csrf,Java,Angular,Spring Security,Csrf,我希望使用Spring安全性(版本5.1.2)为我的Angular 7应用程序生成一个CSRF令牌。我的SecurityConfig文件中包含以下内容: @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnly
@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
会在我的第一次GET
调用中自动生成一个带有头XSRF token
的cookie(这就是/authentication/csrf
的用途),但我不会从服务器返回cookie。因此,在我下一次的POST
通话中,我得到了403的回复。我可能会错过什么
如对我问题的评论所示,我找到了问题的答案无法跨域发送cookie。 我的前端部署在
localhost:3000
上,我的后端部署在localhost:9080
上,这显然是不同的域。如果我转到localhost:9080
(我得到一个白色页面,但这并不重要),然后我转到Chrome中的应用程序选项卡,我发现我一直在寻找的XSRF cookie的存储方式与我一直期待的一样。cookie可以从我从前端执行的GET
调用中获得。问题是cookie需要可用于localhost:3000
,以便Angular可以使用cookie
有多种方法可以在本地环境中解决此问题
使用代理
您可以使用代理将某些url路径映射到后端。这就是我采用的解决方案
我使用Web包开发服务器运行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/*
。因此,在我的例子中,我不再对localhost:9080/api/authentication/csrf
执行GET
调用,而是调用localhost:3000/api/authentication/csrf
,然后将其转发到我的后端。(我在我的rest控制器的路径中添加了/api
,供那些想知道的人使用。)
在同一端口上部署两个应用程序
使用,您可以将前端构建到其dist文件夹,然后让maven将dist文件夹与后端打包以进行部署。我还没有尝试过这个,但是有各种资源表明,使用SpringBoot应该很容易做到这一点。例如,前端和后端都可以通过localhost:9080
获得
使用弹簧配置文件本地禁用csrf
您可以使用Spring@Profile
注释为本地环境和其他环境(测试、验收、生产)创建不同的配置。Csrf可以简单地禁用以进行开发。我不喜欢这个选项,因为我喜欢让开发人员和其他环境尽可能保持一致。这也不是问题陈述的真正答案
如果缺少cookie
XSRF-TOKEN
,它将只创建cookie。查看请求头,看看它是否已经存在。@Andreas我也想到了这一点,但我没有在头中发送任何这样的令牌。我可以在Chrome的应用程序标签中看到cookie并不存在。我相信我已经找到了答案。似乎无法跨域发送cookie。我的angular应用程序托管在localhost:3000上,我的Java后端托管在localhost:9080上。我的选择似乎是要么以某种方式将它们部署在同一个域上,要么使用代理。来源:我在本地也有一个非常类似的设置,但是Spring正在发送XSRF令牌,Angular正在将其发送回Spring。我对这个答案感到非常困惑。