Spring csrf 保护没有按预期工作

问题描述 投票:0回答:1

我实现了一个 CustomCsrfTokenRepository 将 csrf 令牌保存在 postgres 数据库中。

    @Component
public class CustomCsrfTokenRepository implements CsrfTokenRepository {
    private final JpaTokenRepository jpaTokenRepository;

    public CustomCsrfTokenRepository(JpaTokenRepository jpaTokenRepository) {
        this.jpaTokenRepository = jpaTokenRepository;
    }

    @Override
    public CsrfToken generateToken(HttpServletRequest httpServletRequest) {
        String uuid = UUID.randomUUID().toString();
        return new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", uuid);
    }

    @Override
    public void saveToken(CsrfToken csrfToken, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {

        String identifier = httpServletRequest.getHeader("X-IDENTIFIER");
        Optional<Token> existingToken =
                jpaTokenRepository.findTokenByIdentifier(identifier);
        if (existingToken.isPresent()) {
            Token token = existingToken.get();
            token.setToken(csrfToken.getToken());
        } else {
            Token token = new Token();
            token.setToken(csrfToken.getToken());
            token.setIdentifier(identifier);
            jpaTokenRepository.save(token);
        }
    }

    @Override
    public CsrfToken loadToken(HttpServletRequest httpServletRequest) {

        String identifier = httpServletRequest.getHeader("X-IDENTIFIER");
        Optional<Token> existingToken = jpaTokenRepository.findTokenByIdentifier(identifier);
        if (existingToken.isPresent()) {
            Token token = existingToken.get();
            return new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf",
                    token.getToken());
        }
        return null;
    }
}

我将应用程序配置为:

    http.csrf(c -> {
        c.csrfTokenRepository(customTokenRepository);
        c.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler());
    });

我有 2 个端点,一个是

GET
,另一个是
POST
。当我调用
GET
端点时,我的 csrf 令牌未写入数据库。

curl -k -H "X-IDENTIFIER:123456" https://localhost:8080/hello

只有当我调用post请求时,我才能获取保存在数据库中的token。

curl -k -X POST -H "X-IDENTIFIER:123456" -H "X-CSRF-TOKEN:2bc652f5-258b-4a26-b45" https://localhost:8080/hello

这看起来不对。当我调用

GET
请求时,我应该生成令牌并将其保存到数据库,如何实现正确的 csrf 保护?

spring-boot csrf
1个回答
0
投票

Spring Security 在底层管理 csrf 令牌,因此您可以跳过编写此实现。不过,如果您无论如何都想这样做,您还应该实现 CsrfTokenRequestAttributeHandler 接口(您还没有这样做)。请参阅详细的 Spring 文档:https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#csrf-integration-javascript-spa-configuration

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.