Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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;
    }
share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

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$ {
share|improve this answer
2  
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 3 '11 at 14:13
    
Absolutely agree on both suggestions. I've corrected the answer. Thank you! –  Alexander Azarov Jun 3 '11 at 16:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.