Disabling basic_auth with rewrites

Hi,

I would like to generally protect my site but allow one certain path.
However, I need rewrites to forward the requested path to a PHP file.
Unfortunately the following does not work:

location ~ ^/feeds/importer/.* {
auth_basic off;
rewrite ^/(.*)$ /index.php?q=$1;
}

location ~ .php$ {
auth_basic “protected”;
auth_basic_user_file /etc/nginx/htpasswd/protected;
fastcgi_split_path_info ^(.+.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
fastcgi_pass $socket;

workaround as fastcgi_param cannot be used inside if statements

set $https off;
if ($scheme = https) {
set $https on;
}
fastcgi_param HTTPS $https;
fastcgi_read_timeout 6000;
}

location ~ ^/(.*) {
auth_basic “protected”;
auth_basic_user_file /etc/nginx/htpasswd/protected;
try_files $uri /index.php?q=$1&$args;
}

Any ideas how to unprotect the first location?

Posted at Nginx Forum:

Hello!

On Thu, May 19, 2011 at 09:59:37AM -0400, klausi wrote:

if ($scheme = https) {
}

Any ideas how to unprotect the first location?

location / {
    auth_basic "protected";
    auth_basic_user_file /etc/nginx/htpasswd/protected;
    ...

    location ~ \.php$ {
        fastcgi_pass ...
        ...
    }
}

location /feeds/importer/ {
    ...

    location ~ \.php$ {
        fastcgi_pass ...
        ...
    }
}

Maxim D.

Maxim D. Wrote:

    }
}

location /feeds/importer/ {
    ...

    location ~ \.php$ {
        fastcgi_pass ...
        ...
    }
}

Thanks for the quick reply, nested locations are nice, but they do not
help in this special case. A request to /feeds/importer/* has to be
rewritten to /index.php?q=feeds/importer/* and that should not be
protected. Is unprotecting a path with a special query possible at all?

Posted at Nginx Forum:

On Thu, May 19, 2011 at 10:10:59PM +0400, Maxim D. wrote:

/etc/nginx/htpasswd/protected;

        ...

Note that the only goal of rewrite is to properly change url while
correctly escaping new arguments and stripping old ones (note
trailing ‘?’), as you probably don’t want to allow unauthenticated
users to supply arbitrary arguments to your index.php. Due to
‘break’ request doesn’t leave the location in question after
rewrite and processed there.

My suggestion is to not use rewrite at all:

 location /feeds/importer/ {
     location ~ ^/(.*) {
         fastcgi_pass    ...
         fastcgi_param   SCRIPT_FILENAME  /path/to/index.php;
         fastcgi_param   QUERY_STRING     q=$1;
         ...
     }


Igor S.

Hello!

On Thu, May 19, 2011 at 12:43:03PM -0400, klausi wrote:

        fastcgi_pass ...
    }
}

Thanks for the quick reply, nested locations are nice, but they do not
help in this special case. A request to /feeds/importer/* has to be
rewritten to /index.php?q=feeds/importer/* and that should not be
protected. Is unprotecting a path with a special query possible at all?

Ah, sorry, I missed you actually want /feeds/importer/… to be
fully handled by index.php. This makes configuration even
simplier:

location / {
    auth_basic ...
    ...

    location ~ \.php$ {
        fastcgi_pass ...
        ...
    }
}

location /feeds/importer/ {
    rewrite ^/(.*) /index.php?q=$1? break;

    fastcgi_pass ...
    ...
}

Note that the only goal of rewrite is to properly change url while
correctly escaping new arguments and stripping old ones (note
trailing ‘?’), as you probably don’t want to allow unauthenticated
users to supply arbitrary arguments to your index.php. Due to
‘break’ request doesn’t leave the location in question after
rewrite and processed there.

Maxim D.

Hello!

On Thu, May 19, 2011 at 11:16:56PM +0400, Igor S. wrote:

    auth_basic_user_file
    ...

protected. Is unprotecting a path with a special query possible at all?
fastcgi_pass …

     location ~ ^/(.*) {
         fastcgi_pass    ...
         fastcgi_param   SCRIPT_FILENAME  /path/to/index.php;
         fastcgi_param   QUERY_STRING     q=$1;
         ...
     }

There is a problem: you need urlescape() function then. Else
request like

/feeds/importer/&doevil=1

will naturally do evil, i.e. “doevil=1” will be seen by index.php
as a separate argument.

Maxim D.