Spring Security 6.0 CsrfToken行为更改

px9o7tmv  于 2022-11-24  发布在  Spring
关注(0)|答案(1)|浏览(181)

我在6.0-M5、6.0-RC 1和6.0-RC 2版本中测试了Spring Security作为Sping Boot Setup的一部分。我发现了一个行为变化,并想问一下这是否是一个bug。我将CSRF令牌作为序列化的JSON返回,但由于RC 1,JSON中令牌的内容是垃圾。
我在Sping Boot 6 Milestone 5中的工作代码仍按预期工作。

@RestController
public class CsrfController {

    @GetMapping("/rest/user/csrf")
    public CsrfToken csrf(CsrfToken token) {
        return token;
    }

}

在我的用例中,我使用单元测试来查询控制器。

@LocalServerPort
    int serverPort;

    @Autowired
    private TestRestTemplate webclient;

    @Test
    public void getCsrf() {
        ResponseEntity<String> entity = webclient.getForEntity("http://localhost:" + serverPort +
            "/rest/user/csrf", String.class);

        // ... here some code to get the token from the JSON body ...

        assertTrue(result.matches("^[a-f0-9\\-]+$"));

这是服务器的第一次查询。在过去的查询中,客户端和服务器之间没有建立会话对象。这在M5中有效,但在Sping Boot 6 RC 1和RC 2中停止工作
下面的控制器代码使其在RC 2中再次工作:

@GetMapping("/rest/user/csrf")
    public CsrfToken csrf(HttpServletRequest request, HttpServletResponse response) {

        CsrfToken repoToken = tokenRepo.loadToken(request);
        if (repoToken != null) {
            return repoToken;
        }
        // required because it is required but ay not be initialized by the tokenRepo
        request.getSession();

        repoToken = tokenRepo.generateToken(request);
        tokenRepo.saveToken(repoToken, request, response);
        return repoToken;
    }

如果我在RC 2中尝试旧代码,我在客户端收到一个格式错误的字符串。我在JSON序列化响应正文中没有收到UUID样式的令牌。我认为这与未初始化的会话对象有关。
这是一个错误,还是一个未初始化的会话,导致CrsfToken指定的行为不起作用?

gab6jxml

gab6jxml1#

我认为问题出在我尝试获取和使用XSFR令牌的方式上。
因为我想使用Angular前端,所以我配置了令牌库,通过Cookie提供令牌。

http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());

这会产生旧UUID样式的cookie。但是,验证需要https://github.com/spring-projects/spring-security/issues/11960生成的新令牌。可能在最终的Sping Boot 3.0之前,cookie机制仍需要迁移。

相关问题