I would like to block a path from my site using the .htaccess configuration. The idea is that only a specific set of IP's can access that specific path from the URL after they authenticated using basic auth.
Note: It's a path, not a page or directory. We are trying to shield off a web-service so there will be only post calls to the URL's.
I would like the url example.com/rest
to be blocked and everything behind that url based on IP. So example.com/rest/foo
and example.com/rest/foo/bar
should be blocked.
All other paths from the application should remain functional and without basic auth.
The IP blocking part has been resolved in a previous question I asked.
The basic configuration (the blocking part, there is more in the .htaccess but is not relevant to this question.) you can find below.
SetEnvIf Request_URI "/rest(/.*)?$" rest_uri
# Check on what subdomain we are.
SetEnvIf Host ^local\. None_Prod_Env
# Static
SetEnvIf AH_CLIENT_IP ^123\.123\.123\.123$ Allow_Host
# Range
SetEnvIf AH_CLIENT_IP ^123\.123\.123\. Allow_Host
Order deny,allow
Deny from all
Allow from env=!rest_uri
Allow from env=Allow_Host
Allow from env=None_Prod_Env
So the configuration above blocks all access to /rest/* but not to non rest paths, it allows a user coming from IP X (Allow_Host variable) and we allow none production environments in this case local.
I tried to extend this functionality with basic auth like so:
SetEnvIf Request_URI "/rest(/.*)?$" rest_uri
SetEnvIfNoCase Request_URI "/rest(/.*)?$" require_auth=true
# ... Allow Host stuff and none prod stuff ...
Order deny,allow
Deny from all
Allow from env=!rest_uri
Allow from env=Allow_Host
Allow from env=None_Prod_Env
AuthName "Password Protected"
AuthType Basic
AuthBasicProvider file
AuthUserFile /var/www/html/.htpasswd
Require valid-user
However this resulted in a basic auth on all pages and not only for the /rest/* url. I played a lot with it but couldn't figure it out. Changing SetEnvIfNoCase
to SetEnvIf
also didn't help.
Note: Our server is running apache 2.2.22.
You can solve this complex problem using a combination of few Apache directives i.e. mod_dir
, mod_setenv
and mod_auth_basic
:
SetEnvIf Request_URI ^/rest(/.*)?$ rest_uri
# Check on what subdomain we are.
SetEnvIf Host ^local None_Prod_Env
# Static
SetEnvIf AH_CLIENT_IP ^123\.123\.123\.123$ Allow_Host
# Range
SetEnvIf AH_CLIENT_IP ^192\.168\. Allow_Host
RewriteEngine On
# block if request is /rest/* and IP is not whitelisted and not localhost
RewriteCond %{ENV:rest_uri} =1
RewriteCond %{ENV:None_Prod_Env} !=1
RewriteCond %{ENV:Allow_Host} !=1
RewriteRule ^ - [F]
# ask auth for /rest/* && NOT localhost && whitelist IP
AuthType Basic
AuthName "Password Protected"
AuthUserFile /var/www/html/.htpasswd
Require valid-user
Order deny,allow
Deny from all
Allow from env=!rest_uri
Allow from env=!Allow_Host
Allow from env=None_Prod_Env
Satisfy any