Spring 使用 AngularJS 引导和 CSRF - Forbitten 403 -> 错误注销
Spring Boot and CSRF with AngularJS - Forbitten 403 -> wrong logout
在我的 Spring Boot/AngularJS 应用程序中,我有以下 CSRF- 配置:
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(csrfTokenRepository()); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
final String[] restEndpointsToSecure = WebSecurityConfig.restEndpointsToSecure;
for (final String endpoint : restEndpointsToSecure) {
http.authorizeRequests().antMatchers("/" + endpoint + "/**").hasRole(UserRoleEnum.USER.toString());
}
http.addFilterAfter(csrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);
xAuthTokenConfigurer.setDetailsService(userDetailsServiceBean());
final SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> securityConfigurerAdapter = xAuthTokenConfigurer;
http.apply(securityConfigurerAdapter);
}
CSRF- 令牌过滤器如下所示:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain)
throws ServletException, IOException {
final CsrfToken csrf = (CsrfToken)request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
final 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);
}
一般情况下它工作正常,请求 header 属性 X-XSRF-TOKEN 随每个请求一起发送。但是我有一个奇怪的行为。
我将在应用程序中更新我的用户配置文件。第一次它工作正常,第二次,我收到 HTTP 403 Forbidden 实际上我真的不知道为什么。
我在这两个更新之间什么都不做(在这两个更新之间没有导航到其他页面或其他东西)。
最下面的图片,左请求有效,右请求失败。唯一不同的是,在右侧 属性 Set-Cookie 和 X-Application-context 在响应中丢失header。请求 header 是相等的。
有谁知道我在这里做错了什么。这对我来说有点神秘。
您的 front-end
userProfile.controller
中似乎有一些功能 error
Your Cookie SessionID redirected form the request header is getting same in the response header which results in INVALID_SESSIONID hence the user is redirected to the login page or your signup page
作为此问题的解决方案,您可以更正您的前端控制器,或者作为另一种解决方法,您可以将以下内容添加到您的代码中
- 仅在检测到 CORS 时添加 CORS headers 并传递来源 header 以便允许访问用户内容。
使用 http 200 消息响应 OPTIONS 请求
static final String ORIGIN = "Origin";
if (request.getHeader(ORIGIN).equals("null")) {
String origin = request.getHeader(ORIGIN);
response.setHeader("Access-Control-Allow-Origin", "*");//* or origin as u prefer
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers",
request.getHeader("Access-Control-Request-Headers"));
}
if (request.getMethod().equals("OPTIONS")) {
try {
response.getWriter().print("OK");
response.getWriter().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
然后添加要调用的自定义过滤器
//your other configs
< security:custom-filter ref="corsHandler" after="PRE_AUTH_FILTER"/>
在我的 Spring Boot/AngularJS 应用程序中,我有以下 CSRF- 配置:
@Override
protected void configure(final HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(csrfTokenRepository()); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
final String[] restEndpointsToSecure = WebSecurityConfig.restEndpointsToSecure;
for (final String endpoint : restEndpointsToSecure) {
http.authorizeRequests().antMatchers("/" + endpoint + "/**").hasRole(UserRoleEnum.USER.toString());
}
http.addFilterAfter(csrfTokenResponseHeaderBindingFilter(), CsrfFilter.class);
xAuthTokenConfigurer.setDetailsService(userDetailsServiceBean());
final SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> securityConfigurerAdapter = xAuthTokenConfigurer;
http.apply(securityConfigurerAdapter);
}
CSRF- 令牌过滤器如下所示:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain)
throws ServletException, IOException {
final CsrfToken csrf = (CsrfToken)request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
final 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);
}
一般情况下它工作正常,请求 header 属性 X-XSRF-TOKEN 随每个请求一起发送。但是我有一个奇怪的行为。 我将在应用程序中更新我的用户配置文件。第一次它工作正常,第二次,我收到 HTTP 403 Forbidden 实际上我真的不知道为什么。 我在这两个更新之间什么都不做(在这两个更新之间没有导航到其他页面或其他东西)。
最下面的图片,左请求有效,右请求失败。唯一不同的是,在右侧 属性 Set-Cookie 和 X-Application-context 在响应中丢失header。请求 header 是相等的。
有谁知道我在这里做错了什么。这对我来说有点神秘。
您的 front-end
userProfile.controller
error
Your Cookie SessionID redirected form the request header is getting same in the response header which results in INVALID_SESSIONID hence the user is redirected to the login page or your signup page
作为此问题的解决方案,您可以更正您的前端控制器,或者作为另一种解决方法,您可以将以下内容添加到您的代码中
- 仅在检测到 CORS 时添加 CORS headers 并传递来源 header 以便允许访问用户内容。
使用 http 200 消息响应 OPTIONS 请求
static final String ORIGIN = "Origin"; if (request.getHeader(ORIGIN).equals("null")) { String origin = request.getHeader(ORIGIN); response.setHeader("Access-Control-Allow-Origin", "*");//* or origin as u prefer response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers")); } if (request.getMethod().equals("OPTIONS")) { try { response.getWriter().print("OK"); response.getWriter().flush(); } catch (IOException e) { e.printStackTrace(); } }
然后添加要调用的自定义过滤器
//your other configs < security:custom-filter ref="corsHandler" after="PRE_AUTH_FILTER"/>