处理Spring Security在配置好csrf后接口报401问题
现象:接口报401,csrf disable后接口正常200
项目是基于Java Spring boot 2.4.4 写的,原来是csrf是disable的,项目一直跑是没有问题。有一天项目需要配置csrf,不然会有潜在的CSRF风险(跨站请求伪造攻击)。
话不多说,改就完了。
原有配置
http.csrf().disable()
修改后的配置
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()...
可是没有想到,本地跑没有问题,但是部署到服务器上接口就会报401未授权
分析
- 分析服务器上配置和本地的区别,本地没有配置servlet_context_path,但是服务器上因为需要加路径(前后端分离),所以配置了servlet_context_path
- 分析Cookie的Path,加上servlet_context_path后,所有的cookie Path都会加/xxx_context_path
- 所以只有http://xxxx.com/xxx_context_path/下面的页面才有访问这个cookie的权限,如果是SPA(Single Page Application)一般路由是和接口不一样的,所以是无法访问此cookie的
解决方案:配置csrf的Cookie为root path
- WebSecurityConfig.java添加一个函数来获取csrf token repository
private CsrfTokenRepository getCsrfTokenRepository() {
CookieCsrfTokenRepository tokenRepository = CookieCsrfTokenRepository.withHttpOnlyFalse();
//为了支持servlet context path, cookie需要被设置为根目录
tokenRepository.setCookiePath("/");
return tokenRepository;
}
- 修改WebSecurityConfig.java里面的configure函数
原来是:
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()...
修改为:
http.csrf().csrfTokenRepository(this.getCsrfTokenRepository()).and()...