Я пытаюсь заставить функцию запоминания Spring Security работать с Varnish, но это кажется невероятно сложным. При обычном входе это легко, я просто настраиваю Varnish для обхода кеша для URL-адреса j_spring_security_check, но с функцией «запомнить меня» любой URL-адрес может быть точкой входа для входа в систему. Если первое, на что пользователь нажимает, когда открывает свой браузер, — это URL-адрес, который Varnish пропускает (т. е. обходит кеширование), тогда все в порядке, но если пользователь попадает на домашнюю страницу (или на что-либо, что кэшируется Varnish), происходит нечто странное: пользователь входит в систему, я получаю CookieTheftException и, таким образом, cookie-файл Remember-me отменяется, поэтому дальнейший автоматический вход в систему невозможен. Когда я думаю об этом, кажется, что эти двое (remember-me и Varnish) просто никогда не смогут работать вместе! Может ли это быть правдой?
Есть идеи, что могло пойти не так? Как сделать так, чтобы функция Remember-me работала с Varnish? Может ли хэш-функция быть проблемой?
Я публикую части своих конфигураций Varnish ниже (пропущено определение функции хеширования, пожалуйста, сообщите, если вы считаете это уместным):
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;
}
}
ОБНОВЛЕНИЕ: я хорошо задокументировал свою окончательную реализацию здесь.