April 18, 2017
3 min read time

Authentication made easy

These days, almost nothing happens online without authentication. It goes without saying that it has become extremely important. Whether you run a very small internal website or a huge e-commerce platform, it’s almost a guarantee that you will have an authentication layer somewhere in your architecture. The reason is simple: you don't want just anyone to be able to change or access the content or your web application layer.

The authentication mechanism can be implemented at the web application layer:

 

no_auth.png

In an ideal world all clients are well-behaved and execute authentication as requested by the application layer, but in the real world, every web application might have backdoor vulnerabilities that can be manipulated by malicious users to bypass the authentication layer.

Varnish can play a very important role when it comes to authentication. Thanks to the great flexibility VCL provides, Varnish can authenticate clients and make sure they are authorized users instead of leaving this burden to the web application layer.

v_auth.png

In such a scenario, any incoming request will have to go through Varnish where the authentication and the caching happen; therefore, any client request hitting the backend will be an authorized user.

Implementing a simple authentication check in Varnish requires only a few lines of VCL:

sub vcl_recv {
    # unset any authstatus, we don’t want to authenticate user by mistake
    unset req.http.authstatus;
     if (req.http.signature) {
        set req.http.sig-verf = digest.hmac_sha256("key", req.http.host);
        # if the signature header == sig-verf header, then the user is authenticated           
        if (req.http.sig-verf == req.http.signature) {
            set req.http.authstatus = "ok";
        }
    }

    if (req.http.authstatus == "ok") {
        # if the user is authenticated we return a 200 synthetic response
        return(synth(200, "ok"));
    } else {
        # if the user is unauthenticated we return a 401 synthetic response
        return(synth(401, "not ok"));
    }
}

Let me explain:

  1. The client, whenever issuing a request, will have to present a signature (the naming is arbitrary and decided by you) header, which will be used by Varnish to make sure the user can be authenticated.
  2. If the signature header is equal to the signature-verification header (we use libvmod-digest: LINK to get the hmac result) then the user can be authenticated and his/her authentication status is set to “ok”.
  3. Now that you know if the user is authenticated or not, you can implement your own VCL logic based on the authstatus header.

You can copy and paste this VCL snippet and use it as starting point to implement your own authentication.

If you are looking for a more complete solution for both authentication and authorization you might want to read about the Varnish Paywall. To learn more about a real-world implementation of the Varnish Paywall solution, download the case study about RCSMedia Group. 

Download case study