【发布时间】:2015-10-04 11:35:15
【问题描述】:
我有一个 Web 应用程序,背面使用 Java Spring,正面使用 AngularJS。
Spring 安全配置(Java 配置):
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authenticationProvider(authenticationProvider())
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
.and()
.formLogin().loginProcessingUrl("loginProcessingUrl")
.successHandler(authSuccessHandler)
.failureHandler(authFailureHandler)
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout().permitAll().logoutSuccessHandler(logoutSuccessHandler)
.and()
.authorizeRequests().antMatchers("/demo/**","/postTest/**").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(new CsrfCustomFilter(), CsrfFilter.class);
}
CSRF 过滤器:
public class CsrfCustomFilter 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);
}
}
来自 AngularJS 的 POST 请求:
$http({method:'POST',data:"celine",url:"http://localhost:8080/postTest",cache:true})
.success(function(data) {
console.log("success POST");
})
.error(function(data, status, headers, config, statusText) {
console.log("status: " + status + " statusText: " + statusText);
});
-- 更新--
我可以使用从前到后的 GET 请求,但 POST 请求似乎不起作用。我在前端收到 403 Forbidden 错误(在我的日志中:“status: 403 statusText: undefined”)。
对于 POST 请求,我可以正确地向 Spring 发送 XSRF-TOKEN,但 Spring 返回 403 Forbidden。所以我想问题出在我对 Spring Security 的配置上,而不是来自 Angular。
我的 POST 请求标头:
感谢您的宝贵时间。
【问题讨论】:
-
阅读 $http 文档以了解 Angular 如何处理标头中的 xsrf 标记
-
感谢您的帮助。来自文档:“为了利用这个 [CSRF 保护],您的服务器需要在第一个 HTTP GET 请求上设置一个名为 XSRF-TOKEN 的 JavaScript 可读会话 cookie 中的令牌。”但是我想我的问题是因为我的 Spring 端没有发送 XSRF-TOKEN。
-
你不能只添加一个cookie吗?
-
我用 Java 实现了 CsrfCustomFilter 类来发送一个名为 XSRF-TOKEN 的 cookie。但它在我的 POST 请求标头中不可见。但是,它在 GET 响应的标头中可见。
-
你在使用跨域请求吗?我的意思是,您的客户端应用程序与服务器应用程序在不同的端口上运行吗?
标签: angularjs spring rest cookies spring-security