proxy_cache when 'Authorization' HTTP header presents.

Maxim Dounin mdounin at mdounin.ru
Tue Aug 18 16:25:50 MSD 2009


Hello!

On Tue, Aug 18, 2009 at 08:38:03PM +0900, Kuramoto Eiji wrote:

>  On Mon, 17 Aug 2009 18:14:34 +0400
>     Maxim Dounin wrote:
> 
>  } > The proxy_cache module send cached contents until it's expired
>  } > even if a client send wrong user/password after passed first (401)
>  } > authentication. It might be a bug ... ?
>  } 
>  } If authorization checked by nginx - request will never reach this 
>  } stage.  If it's checked by backend server - there is no reason for 
>  } nginx to do anything with it.
> 
> It's checked by backend server.
> 
> my nginx.conf:
> 
>     proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2 keys_zone=one:10m;
> 
>     proxy_cache_key "$host:$server_port$uri$is_args$args";
> 
>     server {
>         listen 8080;
>         server_name frontend-hostname.example.com;
> 
>         location / {
>             proxy_cache one;

Just a side note: proxy_cache meaningless here.

>             error_page 401 404 502 504 = @fallback;
>         }
> 
>         location @fallback {
>             proxy_cache one;
>             proxy_cache_valid 200 1m;
>             proxy_pass http://backend-hostname.example.com;
>         }
> 
> 
> Request/Response:
> 1. client requests HTTP authorization required URI to nginx.
> 2. If it doesn't found in proxy_cached contents, nginx requests URI to
>    backend server.
> 3. backend server responses with 401 (Unauthorized) HTTP status code
>    to nginx.
> 4. nginx responses with 401 (Unauthorized) HTTP status code to client.
> 5. client send requests with the authorized User/Password on
>    'Authorization:' HTTP header.
> 6. nginx passes through that requests to backend server.
> 7. backend server responses authorized contents with 200 HTTP status
>    code without 'Cache-Control: no-cache or no-store' HTTP headers.
> 8. nginx's proxy_cache module caches the contents, so it respond with
>    200 HTTP status code.
> 9. nginx responses the contens to client with 200 HTTP status code.
> 10. change User or Password for HTTP authorization of URI on backend
>     server.
> 11. client requests same URI at step 1 with previously (same at step 5)
>     User/Password (at here, wrong/unauthorized User/Password) on
>     'Authorization:' HTTP header.
> 12. nginx responses previously (at step 8) cached contents without any
>     HTTP authorizations until proxy_cache expired ('proxy_cache_valid'
>     time for '200' HTTP status).
> 
> nginx should request to backend server with 'Authorization:' HTTP
> header requested by client at step 12, I suppose..

No, it shouldn't.  You instructed nginx to cache response - and it 
will do so.  Moreover, it will serve cached response to other 
clients too, even to requests without Authorization header (there 
is no $http_authorization in proxy_cache_key).

>  } This effectively switches off cache for requests with 
>  } authorization.  The same may be done via configs.
> 
> How can I do via configs?

Try something like this:

    location @fallback {
        recursive_error_pages on;
        error_page 405 = @nocache;

        if ($http_authorization) {
            return 405;
        }

        proxy_pass ...
        proxy_cache ...
    }

    location @nocache {
        # no proxy_cache here
        proxy_pass ...
    }

Maxim Dounin





More information about the nginx mailing list