Chr*_*tis 5 java spring multipart spring-security
我想从我的angularJS客户端上传文件.我启用了CSRF保护,它工作正常,除非我尝试上传文件,我得到一个403错误:
在请求参数'_csrf'或标题'X-XSRF-TOKEN'上找到无效的CSRF令牌'null'.
但令牌位于请求标头中并且是正确的!当我禁用CSRF保护时,我可以毫无问题地上传文件.
除此之外,CSRF保护工作正常.
这是我目前的配置:
SecurityConfiguration.java
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityUserDetailsService securityUserDetailsService;
@Autowired
private AuthFailureHandler authFailureHandler;
@Autowired
private AjaxAuthSuccessHandler ajaxAuthSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.exceptionHandling()
.authenticationEntryPoint(authFailureHandler)
.and()
.authorizeRequests()
.antMatchers(
"/",
"/index.html",
"/styles/**",
"/bower_components/**",
"/scripts/**"
).permitAll().anyRequest()
.authenticated()
.and().formLogin().loginPage("/login").permitAll()
.and().logout().logoutUrl("/logout").logoutSuccessHandler(ajaxAuthSuccessHandler).permitAll()
.and().httpBasic()
.and().addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf().csrfTokenRepository(csrfTokenRepository());
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(securityUserDetailsService)
.passwordEncoder(new BCryptPasswordEncoder());
}
}
Run Code Online (Sandbox Code Playgroud)
CsrfHeaderFilter.java
public class CsrfHeaderFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
}
Run Code Online (Sandbox Code Playgroud)
最后我添加了一个SecurityWebApplicationInitializer,如此处所示.
SecurityWebApplicationInitializer.java
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
更新:我添加了此配置,但我仍然得到403.
@Configuration
public class MultipartUploadConfig {
@Bean(name = "filterMultipartResolver")
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您同意将 CSRF 令牌作为 url 参数发送,这是一个快速解决方案。在你的 html 模板中。
<form .... th:action="@{/upload(${_csrf.parameterName}=${_csrf.token})}">
...
</form>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3500 次 |
| 最近记录: |