I have made a terrible, terrible piece of htaccess code as a stop-gap to keep us going, but terrible code makes everyone unhappy. So here it is:
DomainA.com hosts some code we need to pull into DomainB.com and all subdomains of DomainB.com.
Here is the terrible code we came up with and slapped on DomainA.com's htaccess file that works:
<If "%{HTTP_REFERER} == 'https://DomainB.com/testpage1.php'">
</If>
<ElseIf "%{HTTP_REFERER} == 'https://DomainB.com/testpage2.php'">
</ElseIf>
<ElseIf "%{HTTP_REFERER} == 'https://DomainB.com/testpage3.php'">
</ElseIf>
<Else>
AuthType Basic
AuthName "Our Walled Garden - Login Credentials Required"
AuthUserFile /path/to/.htpasswd
Require valid-user
</Else>
Can you help us trim this down so that we don't have to define the protocol or specific subdomain for the request? I've messed around with some regex, I can't get even simple regex matches to work in the IF block.
If you want to use regular expressions, you could use SetEnvIf instead together with an addition Require clause.
Maybe something like:
SetEnvIfNoCase Referer ^https://DomainB\.com/(testpage1|testpage2|testpage3)\.php$ noauth=1
AuthType Basic
AuthName "Our Walled Garden - Login Credentials Required"
AuthUserFile /path/to/.htpasswd
Require valid-user
Require env noauth
When there are multiple Require directives, they are automatically grouped as "Require Any" (See Require apache 2.4 docs ).
The Setenv directive matches against the referer, and if that matches the "noauth" env variable gets set. Then the require directives say either a valid-user or noauth env variable will satisfy the access.
Note that the referer can be easily forged, so this isn't exactly very secure.
Related
Is it possible to require Basic Authentication for all but specified User Agents in Apache configuration?
P.S. I know that User Agents can be easily faked, but for my use case such conditional authentication would be enough.
After searching for quite a bit and experimenting, I came up with the answer. One needs these lines in their .htaccess file:
SetEnvIf User-Agent ^VipAgent1 vip_agent
SetEnvIf User-Agent ^VipAgent2 vip_agent
Order Allow,Deny
Allow from env=vip_agent
AuthType Basic
AuthName "Protected Login"
AuthUserFile /path/to/htpasswd
Require valid-user
Satisfy any
In addition, for this to work, one would need to make sure that mod_rewrite, mod_authn_file, and mod_setenvif are enabled in httpd.conf and also this directive is set there:
AllowOverride All
This configuration gives access for requests with User Agent starting "VipAgent1" and "VipAgent2", but asks for the authentication credentials for all other visitors.
I'm trying to lock down a tree of directories (but allow through image files) using the following .htaccess rule
AuthType Basic
AuthName "Test Sites. *Please Contact xxxxxxx for access.*"
AuthUserFile /home/www/testsites/.htpasswd
Require valid-user
<FilesMatch "\.(gif|jpe?g|png)$">
Satisfy Any
Allow from all
</FilesMatch>
However, when I try it, I'm still being asked to authenticate against images if the image is not directly within the httpdocs directory.
In other words
http://www.testsites.com/test.jpg would be allowed through, but
http://www.testsites.com/sitename/images/test.jpg is asking for authentication.
Any idea why this might be happening?
Try this alternative approach based on mod_setenvif:
SetEnvIfNoCase Request_URI "\.(gif|jpe?g|png)$" ALLOWED
AuthType Basic
AuthName "Test Sites. *Please Contact xxxxxxx for access.*"
AuthUserFile /home/www/testsites/.htpasswd
Require valid-user
Satisfy any
Order deny,allow
Deny from all
Allow from env=ALLOWED
Not exactly sure why this is happening, as the <Files> and <FilesMatch> is supposed to get applied to all the subdirectories. You could try using SetEnvIf instead to match against the entire URI instead of relying on the apache core to first map the URL to a file:
SetEnvIf Request_URI \.(gif|jpe?g|png)$ no_auth=true
AuthType Basic
AuthName "Test Sites. *Please Contact xxxxxxx for access.*"
AuthUserFile /home/www/testsites/.htpasswd
Require valid-user
Satisfy Any
Deny from All
Allow from env=no_auth
I have a development server and a live server. Both use the same .htaccess but I want the development server to be password protected. When I copy the .htaccess file over to the live, I get a 500 error. Does .htaccess offer some way to only password protect directories using conditionals like IF?
what I'm using:
<Directory "/home/my/path/to/development/site/">
AuthName "Restricted Area 52"
AuthType Basic
AuthUserFile /home/my/path/to/development/site/.htpasswd
AuthGroupFile /dev/null
require valid-user
</Directory>
Could really use some help.
You can't have <Directory> containers inside an htaccess file, but you can conditionally turn on or off HTTP auth based on an environment varaible.
So for example, say your production site is http://production.example.com and your dev site is http://dev.example.com then you can check against the HTTP Host and set an environment variable:
SetEnvIfNoCase Host ^dev\.example\.com$ require_auth=true
Or, if the path is different, say your production site is http://example.com/ and dev site is http://example.com/dev/, then you can check against the requested URI:
SetEnvIfNoCase Request_URI ^/dev/ require_auth=true
There's several other checks you can make that's outlined in the mod_setenvif. Either way, you want to set require_auth=true when it's a request for dev. Then you setup your auth stuff to use Satisfy Any:
# Auth stuff
AuthUserFile /home/my/path/to/development/site/.htpasswd
AuthName "Restricted Area 52"
AuthType Basic
# Setup a deny/allow
Order Deny,Allow
# Deny from everyone
Deny from all
# except if either of these are satisfied
Satisfy any
# 1. a valid authenticated user
Require valid-user
# or 2. the "require_auth" var is NOT set
Allow from env=!require_auth
So if require_auth isn't set, then no auth is required, and your SetenvIf should set it if it's a dev request.
I'm trying to build and test a "m." subdomain for a website I'm working on. "m.domain.com" is simply a cname for "domain.com" and will be used to set a server-side boolean so the mobile version of the site will serve exactly the same pages, just with different css and scripts.
While I'm testing, I want to require a password for all requests made to m.domain.com. I've tried several .htaccess variants on environment variable solutions, and this is what I have right now:
SetEnvIfNoCase Host m\.domain\.com is_mobile
AuthType basic
AuthName "Mobile site"
AuthUserFile ".htpasswd"
Require valid-user
Order allow,deny
Allow from all
Deny from env=is_mobile
Satisfy any
With this code, "domain.com" and "www.domain.com" display normally. "m.domain.com" prompts for a password as expected. However, once it's entered, the server returns a 500 error on any request.
Well, turns out that a little inversion and reordering did the trick.
SetEnvIfNoCase Host ^(www\.)domain\.com$ not_mobile
AuthType basic
AuthName "Mobile site"
AuthUserFile ".htpasswd"
Order deny,allow
Deny from all
Allow from env=not_mobile
Require valid-user
Satisfy any
I'm still curious to know why the other configuration created the 500 error, though, especially since it only occurred for the subdomain I wanted password protected.
My hosting has multiple deployments of my site (dev, stage, production). How can I add HTTP Auth headers in my htaccess file if and only if the enviornment variable that they set is equal to 'dev'? (meaning they set a variable called SITE_ENVIRONMENT that can be dev, stage, or prod depending on which site you're accessing.
PS. I'm familiar with requiring authorization from htaccess in vanilla ways, but I'm totally lost when it comes to evaluating variables or writing a block based on the outcome.
You can use SetEnvIf to pattern match the domain and determine which environment to use.
SetEnvIfNoCase Host ^dev.domain.com$ is_on_dev_site
AuthType Basic
AuthName "Protected Login"
AuthUserFile /path/to/.htpasswd
AuthGroupFile /dev/null
Require valid-user
Deny from env=is_on_dev_site
#allow something like API usage to bypass
SetEnvIf Request_URI "(/api/.(.*))$" allow
Order deny,allow
Allow from env=allow
Satisfy any
Man: http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html
I'm not sure this is possible.
Theoreticaly, you can use:
RewriteCond %{ENV:SITE_ENVIRONMENT} ^dev$
to determine which environment you're in, but I can't think of how to write the RewriteRule to force a basic auth... unless you redirected to another page which handles the basic auth and resets the SITE_ENVIRONMENT variable to "dev-authenticated" or something.