The problem is to get the CSRF tokens working between Spring Security and Angular.
问题是要让CSRF令牌在Spring安全性和角度之间工作。
Spring Security CSRF Token Interceptor for Angular seems like something that should do the job, but there is no 'X-CSRF-TOKEN' in the HEAD response from the server.
Spring Security CSRF令牌拦截器的角度看起来像是应该做的工作,但在服务器的头部响应中没有“X-CSRF-TOKEN”。
My current tiny implementation is available in GitHub (Tag v.1.0
) and I would appreciate a lot if somebody who knows the topic would have a quick look on the code, the problem should be easy to spot.
我目前在GitHub (Tag v.1.0)中有一个小的实现,如果知道这个主题的人能够快速查看代码,我将非常感激,这个问题应该很容易发现。
Based on the documentation, I am under the impression that CSRF should have been enabled automatically, but that seems not to be the case.
基于文档,我觉得CSRF应该是自动启用的,但似乎不是这样。
I am using Spring Boot and prefer the annotation-based configuration over XML, if something needs to be configured differently.
我使用Spring引导,更喜欢基于注释的配置而不是XML,如果需要配置不同的配置。
Any other approaches to make Spring Security work against Angular?
还有其他方法可以使Spring安全工作不受影响吗?
2 个解决方案
#1
6
Angular looks for a cookie called "XSRF-TOKEN" I believe, so the easiest thing to do for the client is to send that. You can do it in a Filter
for instance (example from https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/single/src/main/java/demo/UiApplication.java#L65):
我认为,对于一个名为“XSRF-TOKEN”的cookie来说,它是一个很简单的方法,所以对于客户机来说,最简单的方法就是发送它。您可以在一个过滤器中执行它(例如,从https://github.com/spring-guides/tut-spring-security-and-angular- js/blob/master/single/src/main/java/demo/demo/demo/demo/demo/demo/applicationes.java #L65):
private Filter csrfHeaderFilter() {
return new 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 = new Cookie("XSRF-TOKEN", csrf.getToken());
cookie.setPath("/");
response.addCookie(cookie);
}
filterChain.doFilter(request, response);
}
};
}
Update: since spring security 4.2 the correct cookie name for angular is used by default if you use the cookie csrf repository(the link is still the best source), i.e. there is no longer any need for a custom filter. Example:
更新:从spring security 4.2开始,如果使用cookie csrf存储库(链接仍然是最好的源),默认情况下,默认使用角的正确cookie名称,即不再需要自定义过滤器。例子:
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
...
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
#2
1
I am answering the question myself as there was a hidden one in the original GitHub repository: Issue #1.
我自己回答这个问题,因为在GitHub的原始存储库中有一个隐藏的问题:#1。
The solution was to add a couple of lines of Java code that adds the CSRF parameters as Http message headers.
解决方案是添加几行Java代码,将CSRF参数添加为Http消息头。
I added a working solution to the GitHub repo with Tag v.2.0
.
我为GitHub repo添加了Tag .2.0的工作解决方案。
#1
6
Angular looks for a cookie called "XSRF-TOKEN" I believe, so the easiest thing to do for the client is to send that. You can do it in a Filter
for instance (example from https://github.com/spring-guides/tut-spring-security-and-angular-js/blob/master/single/src/main/java/demo/UiApplication.java#L65):
我认为,对于一个名为“XSRF-TOKEN”的cookie来说,它是一个很简单的方法,所以对于客户机来说,最简单的方法就是发送它。您可以在一个过滤器中执行它(例如,从https://github.com/spring-guides/tut-spring-security-and-angular- js/blob/master/single/src/main/java/demo/demo/demo/demo/demo/demo/applicationes.java #L65):
private Filter csrfHeaderFilter() {
return new 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 = new Cookie("XSRF-TOKEN", csrf.getToken());
cookie.setPath("/");
response.addCookie(cookie);
}
filterChain.doFilter(request, response);
}
};
}
Update: since spring security 4.2 the correct cookie name for angular is used by default if you use the cookie csrf repository(the link is still the best source), i.e. there is no longer any need for a custom filter. Example:
更新:从spring security 4.2开始,如果使用cookie csrf存储库(链接仍然是最好的源),默认情况下,默认使用角的正确cookie名称,即不再需要自定义过滤器。例子:
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
...
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
#2
1
I am answering the question myself as there was a hidden one in the original GitHub repository: Issue #1.
我自己回答这个问题,因为在GitHub的原始存储库中有一个隐藏的问题:#1。
The solution was to add a couple of lines of Java code that adds the CSRF parameters as Http message headers.
解决方案是添加几行Java代码,将CSRF参数添加为Http消息头。
I added a working solution to the GitHub repo with Tag v.2.0
.
我为GitHub repo添加了Tag .2.0的工作解决方案。