Spring security 还记得我饼干和清漆吗

Spring security 还记得我饼干和清漆吗,spring-security,varnish,remember-me,Spring Security,Varnish,Remember Me,我试图让SpringSecurity的“记住我”功能与Varnish一起工作,但这似乎非常困难。使用常规登录很容易,我只需设置Varnish以绕过j_spring_security_check URL的缓存,但使用Remembery me,任何URL都可以作为登录的入口点。如果用户打开浏览器时首先点击的是Varnish跳过的URL(即绕过缓存),则一切正常,但如果用户点击主页(或Varnish缓存的任何内容),则会发生奇怪的事情:当用户登录时,我收到CookieTheftException,因此

我试图让SpringSecurity的“记住我”功能与Varnish一起工作,但这似乎非常困难。使用常规登录很容易,我只需设置Varnish以绕过j_spring_security_check URL的缓存,但使用Remembery me,任何URL都可以作为登录的入口点。如果用户打开浏览器时首先点击的是Varnish跳过的URL(即绕过缓存),则一切正常,但如果用户点击主页(或Varnish缓存的任何内容),则会发生奇怪的事情:当用户登录时,我收到CookieTheftException,因此“记住我”cookie被取消,因此,不可能再进行自动登录。 当我想起来的时候,听起来这两个(记住我和Varnish)根本不可能一起工作!这是真的吗

你知道哪里出了问题吗?怎么可能让你记得我涂清漆?散列函数会有问题吗

我在下面发布我的Varnish配置的部分内容(跳过了哈希函数定义,如果您认为相关,请说):


更新:我很好地记录了我的最终实现。

记忆功能通过向服务器发送特殊cookie来工作。服务器知道如何解释cookie值(例如用户名+密码在其中编码,或者它包含一个链接到用户的持久令牌),并且可以为用户进行登录

默认情况下(default.vcl),Varnish不会干扰包含cookie的请求:它们被传递。但是,您的vcl文件不会查看请求cookie,并且指示varnish无论如何都要进行查找(在vcl_recv中)。每个客户端可能都有一个(会话)cookie,因此在许多情况下(但不是所有情况下)忽略请求cookie是有意义的

您的vcl文件应该在vcl_recv中检测到rememberme请求cookie,并相应地进行传递。类似(但请检查cookie名称):


此外,如果您一直有CookiethefteExceptions,请检查是否缓存了任何包含set-cookie头的响应。这样一来,人们就可以进行同样的会话

我也是这么想的。。。但是,跳过包含Spring cookie的所有请求的缓存似乎很有攻击性,所以我就是这么做的。我修改了Spring,以便在成功登录时添加额外的cookie。此cookie是临时的,因此浏览器会在关闭时删除。我为包含Rememberme cookie但缺少此新cookie的请求创建了Varnish skip缓存。这样,登录尝试将不受影响,而所有其他尝试仍将定期缓存。如果用户完全禁用cookie,他们仍然不会触发此规则,因此看起来足够安全。你觉得这个方法怎么样?足够聪明,应该行得通。此外,还要考虑过时的SESSIONID/rememberme cookies。确保在后端删除它们(例如,过期的SESSIONID或无效的rememberme cookie),以便缓存是最佳的。。。我又在想这件事了。。。如果我只是在散列计算中包含用户的memory_ME cookie的值,可能会有所帮助吗?可以,但是每个用户都会为相同的资源(甚至是图像等)获得不同的缓存结果。这将严重影响缓存命中率(缓存资源不会在用户之间共享)。
sub vcl_recv {
    # Forward IP to Apache log
    unset req.http.X-Forwarded-For;
    set req.http.X-Forwarded-For = client.ip;

        if (req.http.host ~ "(?i)mysite\.com$") {
        if (req.restarts == 0) {
                    set req.backend = mysite;
        }
        else {
            error 750 "mysite";
        }
    }

    # static content should always be cached
    if (req.url ~ "\.(js|css|gif|jpg|jpeg|png|swf|flv|txt|pdf|mp3)$") {
        unset req.http.Cookie;
        return(lookup);
    }

    # only cache "get" or "head" requests
    if (req.request != "GET" && req.request != "HEAD") {
        return (pass);
    }

    # do not cache http authentication
    if (req.http.Authorization || req.http.Authenticate) {
        return (pass);
    }

    # do not cache Spring Security URLs, esi, personal pages etc.
        if (req.url ~ "^(/logout|/j_spring_security_check|/personal/)" || req.url ~ "\?service=esi") {
            return(pass);
    }

    return (lookup); # skip default vcl_recv
}

sub vcl_fetch { 
    # Try again if backend not responding
    if (beresp.status != 200 && beresp.status != 403 && beresp.status != 404 && beresp.status != 301 && beresp.status != 302 && beresp.status != 401) {
        return(restart);
    }

    # block sensitive files
    if (req.url ~ "\.(bak|conf|config|ear|exe|gz|jar|log|old|properties|tar|tmp|tgz|war)$") {
        error 405 "Not allowed";
    }

    # do esi processing for all non-static resources
    if (req.url !~ "\.(js|css|gif|jpg|jpeg|png|swf|flv|txt|xml|html|htm|pdf|mp3|doc)$") {       
        esi;
    }

    # do not cache when told not to
    if (req.http.Cache-Control ~ "no-cache") {
        return (pass);
    }

    # do not cache Spring Security URLs, esi, personal pages etc.
    if (req.url ~ "^(/logout|/j_spring_security_check|/personal/)" || req.url ~ "\?service=esi") {
        set beresp.http.Cache-Control = "private, no-cache, no-store, must-revalidate";
        set beresp.http.Pragma = "no-cache";
        set beresp.http.Expires = "Sat, 01 Jan 2000 00:00:00 GMT";
        return(pass);
    }

    # static content should always be cached
    if (req.url ~ "\.(js|css|gif|jpg|jpeg|png|swf|flv|txt|xml|html|htm|pdf|mp3|doc)$") {
        unset beresp.http.set-cookie;
        set beresp.ttl = 1h;
    } else {
        set beresp.ttl = 300s;
    }
}
if (req.http.Cookie ~ "rememberme=" ) {
   return (pass);
}