In a recent case we needed to allow request to a particular virtual URL path on a site that was password protected with HTTP Basic Auth. The site was hosted on a Linux server with Plesk, nginx and Apache. Typically this problem is solved by adding a “Satisfy Any” to the .htaccess in the directory that you want to remove authentication. But this does not work if the path is virtual instead of a physical directory path. Additionally we needed to allow access for a list of IP addresses. We tried an number of different solutions and ended up with the following:
Step 1 – The HTTP Basic Auth and IP access controls are configured in the .htaccess file like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# basic auth AuthName "Authorized Only" AuthType Basic # password file is maintained from Plesk AuthUserFile /var/www/vhosts/system/stage.acme.com/pd/d..httpdocs@donotremove require valid-user # set an environment variable if there is an AUTH_OVERRIDE header SetEnvIf AUTH_OVERRIDE ^true AUTH_REQUEST # set IP controls order deny,allow deny from all allow from 1.1.1.1 allow from 2.2.2.2 # allow request if the environment variable is set allow from env=AUTH_REQUEST # require either Basic Auth or IP controls Satisfy Any |
Step 2 – In Plesk under:
1 |
Subscriptions -> stage.acme.com -> Apache & nginx settings -> Additional nginx directives |
Add the following block:
1 2 3 4 5 6 7 8 9 |
location ~ /excluded/path { proxy_set_header AUTH_OVERRIDE true; proxy_pass http://x.x.x.x:7080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Accel-Internal /internal-nginx-static-location; access_log on; } |
where “/excluded/path” is the virtual URL to be allowed access and “x.x.x.x” is the IP address assigned to the site.
When a request comes is received, nginx looks for the path and adds the AUTH_OVERRIDE header. Then the request is passed to Apache which processes the .htaccess file. The AUTH_OVERRIDE header is converted to an “AUTH_REQUEST” environment variable and allow without authentication by the “allow from env=” rule.
There may be better ways to accomplish this solution but this is one that we successfully implemented.