是否可以向Spring Security CSRF的.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())添加相同站点属性

5tmbdcev  于 2023-02-23  发布在  Spring
关注(0)|答案(3)|浏览(122)

我的安全配置包含以下行:

...csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())...

它会在每个请求中发送一个csrf cookie给客户端。这个cookie没有设置same-site属性。是否也可以添加same-site属性?我查看了该类中的一些方法,并没有发现额外的属性。
如何才能做到这一点?

au9on6nz

au9on6nz1#

不幸的是,从4.0.1版开始,servlet-api不允许你在Cookie中添加Same-Site属性,希望这一点很快会改变。
但同时,您可以提供自己的CsrfTokenRepository实现,直接在HTTP头中设置cookie,而不是将Cookie添加到HttpServletResponse(因此受到servlet-api的cookie表示的限制):

public class CustomCsrfTokenRepository implements CsrfTokenRepository {
    // implement other methods...

    @Override
    public void saveToken(CsrfToken token, HttpServletRequest request,
            HttpServletResponse response) {

        // some version of this:
        response.setHeader("Set-Cookie", "HttpOnly; SameSite=strict");
    }
}

您可以查看CookieCsrfTokenRepository以填补空白。

p1tboqfb

p1tboqfb2#

顺便说一句,按照NatFars的回答,这个解决方案在Kotlin中特别简单,在Kotlin中,你可以委托给其他对象,而不必以黑客的方式从原始对象复制代码:

class CookieCsrfTokenRepositoryWrapper(private val repo: CsrfTokenRepository): CsrfTokenRepository by repo {

    override fun saveToken(token: CsrfToken?, req: HttpServletRequest?, res: HttpServletResponse?) {
        repo.saveToken(token, req, res)
        res?.getHeaders("Set-Cookie")?.toList()?.forEach {
            if(it.contains("XSRF") && !it.contains("SameSite"))
                res.setHeader("Set-Cookie", "$it; SameSite=strict")
        }
    }
}

val repo = CookieCsrfTokenRepositoryWrapper(CookieCsrfTokenRepository.withHttpOnlyFalse())

关于在Kotlin的授权:https://kotlinlang.org/docs/reference/delegation.html

nr9pn0ug

nr9pn0ug3#

从Spring-Security 6.1开始就有了方法
setCookieCustomizer(Consumer<ResponseCookie.ResponseCookieBuilder> cookieCustomizer)
它允许注册一个定制器,如:

final CookieCsrfTokenRepository repo = CookieCsrfTokenRepository.withHttpOnlyFalse();
repo.setCookieCustomizer((x) -> x.sameSite(Cookie.SameSite.NONE.attributeValue()));

相关问题