9

I am trying to configure an nginx 1.12.2 reverse proxy to use auth_request and proxy_cache to authenticate requests to a microservice. End users send a simple Bearer token with their request, and the server tries to fetch a resource with it to determine if they are allowed to proceed. That resource fetch should be cached for a given token to take load off the authentication endpoint. Here's my configuration so far:

ssl_certificate                 /etc/nginx/ssl/certificate;
ssl_certificate_key             /etc/nginx/ssl/key;
proxy_cache_path                /var/cache/nginx/auth_cache levels=1:2 keys_zone=auth_cache:1m max_size=1g inactive=60m;
server {
    listen                      80;
    listen                      443 ssl;
    server_name                 myapi.mydomain.com;
    location / {
        proxy_pass              http://myapi/;
        auth_request            /auth;
    }
    location = /auth {
        internal;
        proxy_pass              https://authendpoint.mydomain.com/api/user/verify;
        proxy_cache             auth_cache;
        proxy_cache_key         "$http_x_auth_token$request_uri";            
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
        proxy_set_header        X-Original-URI $request_uri;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

From a client perspective this is working great, but when I look at the nginx server nothing ever gets written to the cache folder. The folder /var/cache/nginx/auth_cache gets created, but is always empty. What could I be missing?

update

Trying this with newer nginx (1.17.9, currently), we still never see anything written to the cache folder. Elsewhere I saw the suggestion that cookies could block caching - this app doesn't use cookies, but we tried anyway:

location = /auth {
    internal;
    proxy_pass              http://authservice/api/user/verify;
    proxy_cache             auth_cache;
    proxy_cache_key         "$http_x_auth_token$request_uri";   
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
    proxy_set_header        X-Original-URI $request_uri;
    proxy_hide_header       Set-Cookie;
    proxy_ignore_headers    Set-Cookie;
    proxy_set_header        Cookie "";
}

Still the same behavoir; the auth_cache folder is created, but nothing is ever written there, and requests to our auth endpoint are not cached.

Just for reference, the results from our auth endpoint are extremely minimal:

< HTTP/1.1 200 OK
< Date: Sun, 12 Apr 2020 18:04:08 GMT
< Server: Kestrel
< Content-Length: 0

We've also simplified the remote auth endpoint since I originally asked this question. Now, it is a plain http resource running inside the same cluster as the nginx process. I've updated the example above to reflect that.

final update

On the off chance somebody else tries to use this as a reference, in addition to the two helpful answers below, we needed to fix the cache key in the example above:

proxy_cache_key         "$http_x_auth_token$request_uri";            

Only makes sense if you're actually using X-Auth-Token as a header and not just Authorization. The key above will work, but it means the first proxied auth response for any uri will be cached, and the actual token will be ignored. Really, we needed:

proxy_cache_key         "$http_authorization$request_uri";            

2 Answers 2

2
+50

Try upgrading NGINX.

I had the same problem with 1.14.0, where manual requests to /auth with curl were cached, but auth_request sub-requests were not.

After upgrading to NGINX 1.16.1 it started to work.

3
  • Finally got around to trying this again, and still no luck. We're on 1.17.9 now. Apr 12, 2020 at 16:44
  • Since your backend response does not have any cache headers, I'd suggest setting them manually, for example: proxy_cache_valid 200 10s; proxy_cache_valid 403 5s; proxy_cache_valid any 1s; Since auth request are likely to overlap setting proxy_cache_lock on; would also be a good idea. Apr 15, 2020 at 12:18
  • Aha! That was the missing piece. Apr 15, 2020 at 21:15
3

I cannot leave comments because I'm new but the proxy_ignore_headers might help you.

proxy_ignore_headers Expires Cache-Control;

According to the Nginx docs; Disables processing of certain response header fields from the proxied server.

If your app server is returning any "no caching" instructions Nginx will honor them, by ignoring these headers any caching instructions are ignored.

Also, what is the cache status in the http response headers from Nginx at the clients machine. BYPASS will cause nginx to not cache it.

Again, sorry I can't leave a comment but I did want to help if I could.

2
  • Good idea, but unfortunately none of those headers are present. The example response is complete - the only headers are Date, Server, and Content-Length Apr 14, 2020 at 15:39
  • At least I can comment now that you commented to me. I had great difficulty getting all the caching with Nginx working. I have to manually create the cache folder too before it started. I believe you need to manually add the cache-status header in your .conf. eg; add_header X-Cache $upstream_cache_status; Apr 14, 2020 at 20:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .