Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Security未创建CSRF令牌_Java_Angular_Spring Security_Csrf - Fatal编程技术网

Java Spring Security未创建CSRF令牌

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

我希望使用Spring安全性(版本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
会在我的第一次
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。我对这个答案感到非常困惑。