I’ve been asked about this so many times that I thought I should just post it here. It’s actually very simple to do using restarts.
The problem: you need to check if a user is authorized for an object (which may or may not already be cached by Varnish) by means of an external application.
The solution: the following VCL will pass GET requests from the users to the authorization app. You can modify the URLs, e.g. insert a custom query string if required by the app.
The request is then either denied (if the auth app returns anything other than a 200) or restarted and served from the real backend or from cache.
This is only an example; you can extend it to cache authorization responses, add a control header if you use restarts anywhere else in your VCL, etc.
sub vcl_recv {
if (req.url ~ "^/authorized_content") {
if (req.restarts == 0) {
set req.backend = authorization_backend;
return(pass);
} else {
set req.backend = real_backend;
set req.url = regsub(req.url, "_authorize_me", "");
}
}
}
sub vcl_fetch {
if (req.url ~ "^/authorized_content" && req.restarts == 0) {
if (beresp.status == 200) {
restart;
} else {
error 403 "Not authorized";
}
}
}
fajne/smart. we’ve been doing this with esi so far, but this one require way less effort from webapp. if i understand this correctly it should remove authorized_content prefix in line 8 and not _authorize_me.
Thanks. Actually, it removes
_authorize_meintentionally in the example; the idea was to ask for e.g./authorized_content/foobar.flv_authorize_me, process the authorization and then request/authorized_content/foobar.flvfrom the real backend. Obviously this is just a silly example. :-)Thank u
Thanks. Works great.