Spring单页应用程序:CSRF令牌在登录,注销等后无提示更改 [英] Spring Single Page Application: CSRF token changing silently after login, logout etc

查看:219
本文介绍了Spring单页应用程序:CSRF令牌在登录,注销等后无提示更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,在Spring + JavaScript单页应用程序中,我们需要以某种方式将CSRF令牌发送给客户端.

As I know, in a Spring+JavaScript single page application, we need to send the CSRF token to the client in some way.

建议的方法是拥有一个CsrfHeaderFilter,如春季指南.按照这种方法,当应用程序启动时,它将向服务器发送GET请求,从而获取令牌.

A recommended way would be to have a CsrfHeaderFilter as described in this Spring guide. Following this approach, when the application will start, it will send a GET request to the server, thus fetching the token.

但是我看到在某些情况下,例如 login logout ,Spring Security会更改令牌. CsrfHeaderFilter是预先出现的,因此无法检测到更改.因此,我需要在此类事件之后发送另一个GET请求.

But I see that under certain events like login or logout, Spring Security changes the token. CsrfHeaderFilter comes beforehand, and so can't detect the change. Hence, I am needing to send another GET request following such events.

我尝试窥视Spring Security代码,以查找是否有一种方法可以将更改的令牌与这些 login logout 请求一起发送,以便另一个GET请求已保存.但是,找不到方法.

I tried peeping at the Spring Security code to find if there would be a way to send the changed token along with these login or logout requests, so that another GET request is saved. But, could not find a way.

就像我现在所做的那样,我想知道在登录注销等之后是否发送虚拟的GET请求,这似乎是一个不错的解决方案.或者,也许有更好的方法?

Liked to know if sending a dummy GET request after login, logout etc., as I am now doing, looks like a good solution. Or, maybe there is a better way?

如果当前没有办法避免这个冗余的GET请求,我想知道这是否成为Spring Security提出一些事情的票证,然后才有可能.

If there is currently no way to avoid this redundant GET request, I was wondering if this becomes a ticket for Spring Security to come up with something after which it would be possible.

推荐答案

了解关于CookieCsrfTokenRepository的类似情况.

Came across with the similar situation regarding CookieCsrfTokenRepository.

我研究的应用程序具有通过REST服务进行登录的自定义实现.该服务中有httpServletRequest.logout()调用(据我所知),该响应导致清除XSRF-TOKEN cookie作为响应:

The application I worked on has a custom implementation of login with via REST-service. The service has httpServletRequest.logout() call inside that (as I figured out) led to clearing of XSRF-TOKEN cookies in response:

Set-Cookie:XSRF-TOKEN=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/ibdrs; Secure

答案中没有新的XSRF-TOKEN值,我有两个选择:

Without new XSRF-TOKEN value in the answer I had two options:

  1. 在登录后立即发出虚拟的get请求以获取新的XSRF-TOKEN(如OP所建议的那样)

  1. Make a dummy get request to obtain new XSRF-TOKEN right after login (as the OP suggested)

在相同的登录响应中获取更新的XSRF-TOKEN,而不是清除cookie.

Get updated XSRF-TOKEN in the same login response instead of clearing cookie.

事实证明,第二种选择可以通过以下方式实现:

It turned out that the second option could be achieved by:

  1. 制作了我自己的CustomCookieCsrfTokenRepository作为CookieCsrfTokenRepository的副本(源代码为

  1. Made my own CustomCookieCsrfTokenRepository as the copy of CookieCsrfTokenRepository (the source code is here). If it wasn't final it would be sufficient to extend it instead of copying.

将副本中所有出现的CookieCsrfTokenRepository更改为CustomCookieCsrfTokenRepository

Changed all the occurrences of CookieCsrfTokenRepository to CustomCookieCsrfTokenRepository inside the copy

用永不清除cookie的新版本替换了saveToken方法:

Replaced saveToken method with new version that never clears the cookie:

@Override
public void saveToken(CsrfToken token, HttpServletRequest request,
                  HttpServletResponse response) {
    if (token == null) {
        token = generateToken(request);
    }
    String tokenValue = token.getToken();
    Cookie cookie = new Cookie(this.cookieName, tokenValue);
    cookie.setSecure(request.isSecure());
    if (this.cookiePath != null && !this.cookiePath.isEmpty()) {
        cookie.setPath(this.cookiePath);
    } else {
        cookie.setPath(this.getRequestContext(request));
    }
    cookie.setMaxAge(-1);
    if (cookieHttpOnly && setHttpOnlyMethod != null) {
        ReflectionUtils.invokeMethod(setHttpOnlyMethod, cookie, Boolean.TRUE);
    }
    response.addCookie(cookie);
}

  • 将HttpSecurity配置为使用新类:

  • Configured HttpSecurity to use the new class:

    .csrf()
        .csrfTokenRepository(CustomCookieCsrfTokenRepository.withHttpOnlyFalse())
        .and()
    

  • 这篇关于Spring单页应用程序:CSRF令牌在登录,注销等后无提示更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆