0

I am trying to secure couple of locations using the basic HTTP authentication that comes with Nginx, but for some reason it won't work.

I have:

website.com/admin (This is accesible by user ADMIN) website.com/admin/secret.php (This is accessible only by user SECRET)

I used to have it working in Lighttpd:

"/admin/secret.php" => (
    "method"  => "basic",
    "realm"   => "Server Administrator",
    "require" => "user=SECRET"
    ),

"/admin" => (
    "method"  => "basic",
    "realm"   => "Administrators",
    "require" => "user=ADMIN"
    )

Any ideas how this can be converted to Nginx. I've tried with the following, but only ADMIN will ask for password:

location /admin/secret.php {
    auth_basic "Restricted";
    auth_basic_user_file /home/passwords/SECRET;
    try_files $uri = 404;
    fastcgi_pass localhost:9000;
    }

location ^~ /admin/.+\.php$ {
    auth_basic "Restricted";
    auth_basic_user_file /home/passwords/ADMIN;
    try_files $uri = 404;
    fastcgi_pass localhost:9000;
    }
uloBasEI
  • 676
  • 1
  • 4
  • 11
Ivo Sabev
  • 177
  • 1
  • 1
  • 5

1 Answers1

3

Nginx rules for processing locations are as follows: it enumerates all ordinary locations and finds the most exact match (Nginx sorts all ordinary locations to optimize this step). After that, Nginx runs all "regexp" locations in order of their appearance. If any "regexp" location succeeds, Nginx will use this first match. If no "regexp" location succeeded, Nginx uses the ordinary location found on the previous step.

In your case, since "regexp" locations have precedence over "prefix" locations, that's why your /admin/.+\.php$ is selected to process request to /admin/secret.php.

It is possible to prohibit searching regexp locations using ^~ modifier or specify an exact match using = modifier:

location = /admin/secret.php { ...

Note I've just noticed the configuration fragment in your question is wrong -- you have ^~ in front of regexp, where ~ should be. What you should have is:

location = /admin/secret.php {

location ~ ^/admin/.+\.php$ {
Alexander Azarov
  • 3,510
  • 20
  • 19
  • 3
    location = would probably be more appropriate than ^~ for /admin/secret.php, since it's an exact match, not a prefix. Also, the regex location should be anchored using ^ to match the beginning of the request. – kolbyjack Jun 03 '11 at 14:13
  • Absolutely agree on both suggestions. I've corrected the answer. Thank you! – Alexander Azarov Jun 03 '11 at 16:08