Auth before serving from cache/backend

Laurence Rowe l at lrowe.co.uk
Fri Jul 22 15:17:23 CEST 2011


On 22 July 2011 11:28, Sumit Raja <sumitraja at gmail.com> wrote:
> Hello,
>
> I am evaluating Varnish to put in front of an authenticated web application.
> Essentially I am trying to get Varnish to make a HEAD request to the back
> end for authentication before it serves from cache or passes the GET
> downstream. The web app uses basic auth.
>
> My first attempt seems to work, that is the HEAD request is made and content
> is cached correctly, until the HEAD to the back end results in a 401. From
> this point on Varnish always serves the 401 for that request, even after
> making the HEAD and getting a 2xx from the back end.
>
> I'm pretty sure I am missing something basic as this is my first attempt but
> some help would be appreciated with my config. The VCL is:
>
> sub vcl_recv {
>     if (req.request != "GET" &&
> .
> . //from default.vcl
> .
> .
> .// virtual host selection
> .
>
>     if (req.restarts == 0) {
>         .
>         . // X-forwarded for from default.vcl
>         .
>         if (req.http.Authorization && req.backend == api) {
>             return(pass);
>         }
>     }
>     return (lookup);
> }
>
> sub vcl_pass {
>    if (req.http.Authorization && req.backend == api && req.restarts == 0) {
>        set bereq.request = "HEAD";
>    }
>    return (pass);
> }
>
> sub vcl_fetch {
>
>     if (req.http.Authorization && req.backend == api && req.restarts == 0) {
>         if (beresp.status >= 200 && beresp.status < 400) {
>             return(restart);
>         } elsif (beresp.status != 401) {
>             return(error);
>         } else {
>             error 401 "Not Authorised";
>         }
>     } else {
>         if (beresp.ttl <= 0s ||
>             beresp.http.Set-Cookie ||
>             beresp.http.Vary == "*") {
>             set beresp.ttl = 120 s;
>             return (hit_for_pass);
>         }
>         return (deliver);
>     }
> }
>

See this diagram of the flow in VCL:
https://www.varnish-cache.org/trac/wiki/VCLExampleDefault

You probably want something like this instead of your vcl_pass:

 sub vcl_hit {
    if (req.http.Authorization && req.backend == api && req.restarts == 0) {
        set bereq.request = "HEAD";
        return (pass);
    }
 }

Laurence




More information about the varnish-misc mailing list