我有一个适用于Spring的Angular2应用程序。后端(弹簧)在另一个端口上运行,因此我将CORS配置如下。
$.each(data.posts, function(key, value) {
var cat = data.posts[ind].tags[key].title;
var apCat = '<li><input type="checkbox" id="tagPol' + key + '" value=" " class="tag"><label for="tagPol' + key + '" class="inter-label">' + cat + '</label></li>';
$('#post-inter-tags').append(apCat);
});
此代码工作正常我猜是因为我没有收到任何错误。
当我尝试POST一些东西时会出现问题,但它可以使用GET方法正常工作。我在我的弹簧配置中启用了CSRF,我希望它能保持这种状态。我尝试POST时收到'403'代码。这是我用于配置CSRF的CookieFilter类。
public GlobalCorsfilter() {
super();
}
@Override
public final void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain) throws IOException, ServletException {
final HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");
// without this header jquery.ajax calls returns 401 even after successful login and SSESSIONID being succesfully stored.
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Authorization, Origin, Content-Type, Version");
response.setHeader("Access-Control-Expose-Headers", "X-Requested-With, Authorization, Origin, Content-Type");
final HttpServletRequest request = (HttpServletRequest) req;
if (request.getMethod() != "OPTIONS") {
chain.doFilter(req, res);
} else {
//
}
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
这是我的Spring配置:
public class CsrfCookieGeneratorFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// Spring put the CSRF token in session attribute "_csrf"
CsrfToken csrfToken = (CsrfToken) request.getAttribute("_csrf");
// Send the cookie only if the token has changed
String actualToken = request.getHeader("X-CSRF-TOKEN");
if (actualToken == null || !actualToken.equals(csrfToken.getToken())) {
// Session cookie that will be used by AngularJS
CookieGenerator cookieGenerator = new CookieGenerator();
cookieGenerator.setCookieName("CSRF-TOKEN");
cookieGenerator.setCookieHttpOnly(false);
cookieGenerator.setCookieMaxAge(-1);
cookieGenerator.setCookiePath("/");
cookieGenerator.addCookie(response, csrfToken.getToken());
}
filterChain.doFilter(request, response);
}
我已经在Angular 2中添加了这行代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(new GlobalCorsfilter(), ChannelProcessingFilter.class)
.addFilterAfter(new CsrfCookieGeneratorFilter(), CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.........
我在回复中收到此消息:
{provide: XSRFStrategy, useValue: new CookieXSRFStrategy('CSRF-TOKEN', 'X-CSRF-TOKEN')}
答案 0 :(得分:1)
根据Angular2文档,如果您使用http方法,它默认处理CSRF,因此您不需要添加任何提供程序,除非您想要自定义XSRFstrategy。
Angular的http在其XSRFStrategy中内置了对该技术的客户端一半的支持。默认的CookieXSRFStrategy会自动打开。在发送HTTP请求之前,CookieXSRFStrategy会查找名为XSRF-TOKEN的cookie,并使用该cookie的值设置名为X-XSRF-TOKEN的标头。
https://angular.io/docs/ts/latest/guide/security.html#!#http
但正如您在下面的链接中所看到的,您需要在spring中进行特殊配置才能允许JavaScript(即AngularJS)读取它。在文档中,他们命名为AngularJS,但与Angular 2 +相同。
http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-cookie