Use HTTP Auth only if accessing a specific domain - apache

I've got several sites: example.com, example1.com, and example2.com. All of them point to my server's /public_html folder, which is my Apache root folder.
What do I need to add to my .htaccess file to use http authentication only if the user is coming from example2.com? example.com and example1.com should NOT use authentication.
I know I need something like
AuthType Basic
AuthName "Password Required"
AuthUserFile "/path/to/.htpasswd"
Require valid-user
But I only want to require a password if the user is visiting example2.com.
Edit
Using an approach suggested in an answer, I have the following in my .htaccess file:
SetEnvIfNoCase Host ^(.*)$ testauth
<IfDefine testauth>
RewriteRule ^(.*)$ index2.php?q=$1 [L,QSA]
</IfDefine>
I know that the mod_setenvif.c module is enabled (I verified with an <IfModule> block), but it would appear that "testauth" is never getting defined, because my test to verify (redirecting to index2.php) is not executing (whereas it was getting executed in my <IfModule> block). Any ideas why?

How about something along the lines of this in the htaccess file in the document root:
# set the "require_auth" var if Host ends with "example2.com"
SetEnvIfNoCase Host example2\.com$ require_auth=true
# Auth stuff
AuthUserFile /var/www/htpasswd
AuthName "Password Protected"
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
This will make it so authentication is not required unless the host ends with example2.com (e.g. www.example2.com, dev.example2.com, etc). The expression can be tweaked if needed. Any other host will cause the require_auth var not to get set so authentication is not required. If this needs to be the other way around, the last line could be changed to: Allow from env=require_auth, removing the !.

Apache 2.4 offers a semantic alternative with the If directive:
<If "req('Host') == 'example2.com'">
AuthUserFile /path/to/htpasswd
AuthType Basic
AuthName "Password Protected"
Require valid-user
</If>
<Else>
Require all granted
</Else>

Here is one recommendation:
Create a file called common.conf and save in an accessible location
In this file place the Apache configuration common to all sites (hosts).
The remove the current single VirtualHost entry an replace with VirtualHost entries as follows:
# These are the password protected hosts
<VirtualHost *:80>
ServerName example.com
ServerAlias example1.com
Include /path-to-common-configuration/common.conf
AuthType Basic
AuthName "Password Required"
AuthUserFile "/path/to/.htpasswd"
Require valid-user
</VirtualHost>
# These are hosts not requiring authentication
<VirtualHost *:80>
ServerName example2.com
ServerAlias example3.com
Include /path-to-common-configuration/common.conf
</VirtualHost>

I wonder if DanH would be helped by an approach that allows access per IP address?
Something like
SetEnvIf Remote_Addr 1\.2\.3\.4 AllowMeIn
SetEnvIfNoCase Host this\.host\.is\.ok\.com AllowMeIn
SetEnvIfNoCase Host this\.host\.is\.also\.ok\.com AllowMeIn
and then in your Drupal "container"
Order Allow,Deny
Allow from env=AllowMeIn
should do the trick.
Any host that is "live" should be configured to "AllowMeIn", or else you have to come from a known IP address (ie you and other developers).

You shouldn't be putting per-vhost configuration into .htaccess. Instead, put the config block in the VirtualHost block in the proper config file in /etc/apache/sites-enabled/*.

Related

Litespeed Enterprise not obeying .htaccess require rules

I have the following folder structure
domain.com (/public_html/)
sub.domain.com (/public_html/sub/)
sub.domain.com/dir1/ (/public_html/sub/dir1/)
sub.domain.com/dir1/dir2/ (/public_html/sub/dir1/dir2/)
if I put the following in my .htaccess file at any of these directories
DirectoryIndex index.php
require valid-user
<RequireAny>
Require ip x.x.x.x
</RequireAny>
It has no effect when loading any files in these directories.
Additionally if i want multiple require rules to have and/or then it gets a little more complicated for example
# Allowing Access via Password or one of the following IP Addresses
AuthName "Authorized Only"
AuthType Basic
AuthUserFile /home/.htpasswds/.htpasswd
<RequireAll>
require valid-user
<RequireAny>
Require ip x.x.x.x
Require ip y.y.y.y
</RequireAny>
</RequireAll>
Apache did follow these rules set, but switching to litespeed enterprise web server has meant that IP restrictions have been ignored
What am I missing here?
require valid-user
<RequireAny>
Require ip x.x.x.x
</RequireAny>
This would seem to be overkill for Apache 2.4. <RequireAny> is the default container. The above 4 lines is the same as the one-line Require ip x.x.x.x.
However, my experience with LiteSpeed is that it behaves more like an Apache 2.2 server and (annoyingly) silently fails on directives it does not understand (although there might be something logged in the server's error log).
Try the following (Apache 2.2 style) directives instead:
Order Allow,Deny
Allow from x.x.x.x

svn ldap automatic authorisation

When we decided to move to LDAP auth for SVN I had assumed that authentication & authorisation would be automatic, i.e. if a user is logged into the network, subversion would accept the user as legitimate and not pop up a login dialog, but just get on with life. Unfortunately, so far we have not achieved this.
It causes problems with, amongst other things, my Source Control extranet web application which used to do a user password lookup (not secure) but now must request authorisation.
Should SVN/LDAP work like I had hoped? If so, is there some arcane config item I need to set? What am I missing?
This, I think, is the appropriate .conf [redacted and obfuscated, of course]
#
#
# DO NOT EDIT THIS FILE IT WILL BE REGENERATED AUTOMATICALLY BY SUBVERSION EDGE
#
# If you must make a change to the contents of this file then copy and paste the
# content into the httpd.conf file and comment out the Include statement for
# this file. The httpd.conf file is not modified or generated and is safe for
# you to modify.
#
#
Include "F:\csvn\data/conf/ctf_httpd.conf"
<VirtualHost *:18080>
# SSL is off
# Required for SCRIPT_URI/URL in viewvc libs, not just rewrite rules
RewriteEngine on
RewriteOptions inherit
# Apache will issue sub_req for PATH_INFO on ScriptAlias which
# gives a spurious error message. Setting auth at root level to avoid clogging logs.
<Location />
AuthType Basic
AuthName "CollabNet Subversion Repository"
AuthBasicProvider file ldap
AuthLDAPUrl "ldap://192.168.0.249:3268/OU=Technical Staff,OU=DomainUsers,DC=snip,DC=net?samAccountName?sub" "NONE"
AuthLDAPBindDN "CN=subversion,OU=Technical Staff,OU=DomainUsers,DC=snip,DC=net"
AuthLDAPBindPassword "kasd8asdik"
LDAPReferrals Off
AuthUserFile "F:\csvn\data/conf/svn_auth_file"
Require valid-user
</Location>
# Work around authz and SVNListParentPath issue
RedirectMatch ^(/svn)$ $1/
<Location /svn/>
DAV svn
SVNParentPath "F:/csvn/data/repositories"
SVNReposName "CollabNet Subversion Repository"
<IfModule deflate_module>
SetOutputFilter DEFLATE
</IfModule>
AuthzSVNAccessFile "F:\csvn\data/conf/svn_access_file"
SVNPathAuthz short_circuit
SVNListParentPath On
</Location>
<Directory "F:\csvn\www\viewVC/docroot">
AllowOverride None
Options None
</Directory>
<Location /viewvc-static>
Require all granted
</Location>
Alias /viewvc-static "F:\csvn\www\viewVC/docroot"
ScriptAlias /viewvc "F:\csvn\bin/cgi-bin/viewvc.cgi"
<Location /viewvc>
AddDefaultCharset UTF-8
SetEnv CSVN_HOME "F:\csvn"
</Location>
</VirtualHost>
#
# auth helper endpoint for use by SvnEdge
#
<VirtualHost localhost:50123>
<Location "/">
AuthType Basic
AuthName "CollabNet Subversion Repository"
AuthBasicProvider file ldap
AuthLDAPUrl "ldap://192.168.0.249:3268/OU=Technical Staff,OU=DomainUsers,DC=snip,DC=net?samAccountName?sub" "NONE"
AuthLDAPBindDN "CN=subversion,OU=Technical Staff,OU=DomainUsers,DC=snip,DC=net"
AuthLDAPBindPassword "kasd8asdik"
LDAPReferrals Off
AuthUserFile "F:\csvn\data/conf/svn_auth_file"
Require valid-user
</Location>
</VirtualHost>
Should SVN/LDAP work like I had hoped?
Yes
If so, is there some arcane config item I need to set?
Probably
What am I missing?
Show your full SVN-related location (from Apache, you have use it?!)

How to make Basic Auth exclude a rewritten URL

I have a Basic Authentication setup on a development server. It is setup inside my httpd.conf file for the VirtualHost of the website. I've had to set up it to exclude certain directories, which has caused no problems and all works fine.
The issue has been with excluding a URL that has been through my mod_rewrite rules in the .htaccess file. My set up is that I have all URLs going through my index.php file and from there the relevant code is found and ran. I tried adding the URL that I wanted to exclude (/businesses/upload_logo) like I did the others but it still requires authentication. This is what I currently have:
...
<Location />
SetEnvIf Request_URI "/businesses/upload_logo" noauth=1
SetEnvIf Request_URI "/api/.*" noauth=1
AuthType Basic
AuthName "Private"
AuthUserFile ****
Require valid-user
Order deny,allow
Satisfy any
Deny from all
Allow from env=noauth
</Location>
....
I have found questions that are similar to mine here & here but the answers only give me what I'm already trying.
I have thought of possible other solutions as well, but these will be last resort things. I want to see if it's possible the way I'm currently doing it:
Set up the basic auth inside my php code instead
Too much hassle at the moment
Put the authentication in my .htaccess file instead
Didn't want to do this just yet as I only want the authentication to happen on one of 3 servers. I'm aware that I could use some more SetEnvIf HOST ... but I'm looking to see if it can be fixed this way or not first.
The mod_rewrite rule:
...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php [L,QSA]
Try adding
Allow from env=REDIRECT_noauth
For me something like this works like a charm:
<location />
SetEnvIf Request_URI "/businesses/upload_logo" REDIRECT_noauth=1
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /etc/httpd/passwords/passwords
Order Deny,Allow
Satisfy any
Deny from all
Allow from env=REDIRECT_noauth
Require user yournickname
</location>
based on what you have given it should work, unless there is a conflicting directive somewhere else in your configuration.
i have made a similar working setup , just i have used filesystem path instead of URI
i am adding it here, hoping you may find it useful
<VirtualHost *:8989 >
<IfModule mod_auth_basic.c>
<Directory /var/www/html/vella-8989>
# the auth block
AuthType Basic
AuthName "Please login."
AuthUserFile /var/www/html/vella-8989/.htpasswd
require valid-user
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=noauth
</Directory>
</IfModule>
# set an environtment variable "noauth" if the request has "/callbacks/"
SetEnvIf Request_URI "/callbacks/" noauth=1
ServerName vella.com
ServerSignature off
</VirtualHost>

htaccess exclude one url from Basic Auth

I need to exclude one Url (or even better one prefix) from normal htaccess Basic Auth protection. Something like /callbacks/myBank or /callbacks/.*
Do you have any hints how to do it?
What I'm not looking for is how to exclude a file.
This has to be url (as this is solution based on PHP framework, and all urls are redirected with mod_rewrite to index.php). So there is no file under this URL. Nothing.
Some of those urls are just callbacks from other services (No IP is not known so I cannot exclude based on IP) and they cannot prompt for User / Password.
Current definition is as simple as:
AuthName "Please login."
AuthGroupFile /dev/null
AuthType Basic
AuthUserFile /xxx/.htpasswd
require valid-user
Using SetEnvIf, you can create a variable when the request starts with some path, then use the Satisfy Any directive to avoid having to login.
# set an environtment variable "noauth" if the request starts with "/callbacks/"
SetEnvIf Request_URI ^/callbacks/ noauth=1
# the auth block
AuthName "Please login."
AuthGroupFile /dev/null
AuthType Basic
AuthUserFile /xxx/.htpasswd
# Here is where we allow/deny
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=noauth
The allow/deny chunk of directives says that deny access for EVERYONE, except when there is a valid-user (successful BASIC auth login) or if the noauth variable is set.
If you are using Apache 2.4, SetEnvIf and mod_rewrite workarounds are no longer necessary since the Require directive is able to interpret expressions directly:
AuthType Basic
AuthName "Please login."
AuthUserFile "/xxx/.htpasswd"
Require expr %{REQUEST_URI} =~ m#^/callbacks/.*#
Require valid-user
Apache 2.4 treats Require directives that are not grouped by <RequireAll> as if they were in a <RequireAny>, which behaves as an "or" statement. Here's a more complicated example that demonstrates matching both the request URI and the query string together, and falling back on requiring a valid user:
AuthType Basic
AuthName "Please login."
AuthUserFile "/xxx/.htpasswd"
<RequireAny>
<RequireAll>
# I'm using the alternate matching form here so I don't have
# to escape the /'s in the URL.
Require expr %{REQUEST_URI} =~ m#^/callbacks/.*#
# You can also match on the query string, which is more
# convenient than SetEnvIf.
#Require expr %{QUERY_STRING} = 'secret_var=42'
</RequireAll>
Require valid-user
</RequireAny>
This example would allow access to /callbacks/foo?secret_var=42 but require a username and password for /callbacks/foo.
Remember that unless you use <RequireAll>, Apache will attempt to match each Require in order so think about which conditions you want to allow first.
The reference for the Require directive is here: https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require
And the expression reference is here: https://httpd.apache.org/docs/2.4/expr.html
This solution works pretty well, you just need to define whitelist you want to pass through.
SetEnvIfNoCase Request_URI "^/status\.php" noauth
AuthType Basic
AuthName "Identify yourself"
AuthUserFile /path/to/.htpasswd
Require valid-user
Order Deny,Allow
Deny from all
Allow from env=noauth
Satisfy any
I tried the other solutions but this is what worked for me. Hopefully it will be of help to others.
# Auth stuff
AuthName "Authorized personnel only."
AuthType Basic
AuthUserFile /path/to/your/htpasswd/file
SetEnvIf Request_URI "^/index.php/api/*" allow
Order allow,deny
Require valid-user
Allow from env=allow
Deny from env=!allow
Satisfy any
This will allow the api url and any url string after /index.php/api/ to open without having to login and anything else will be prompted to login.
Example:
mywebsite.com/index.php/api will open without being prompted to login
mywebsite.com/index.php/api/soap/?wsdl=1 will open without being prompted to login
mywebsite.com will be prompted to login first
<location />
SetEnvIf Request_URI "/callback/.*" REDIRECT_noauth=1
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /etc/httpd/passwords/passwords
Order Deny,Allow
Satisfy any
Deny from all
Allow from env=REDIRECT_noauth
Require user yournickname
</location>
why don't you just use basic auth the way it was intended?
user:password#domain.com/callbacks/etc
Another approach works like this, if the area you are protecting has a monolithic PHP script controlling everything, like Wordpress. Set up Authentication with in a different directory. Put an index.php there that sets a cookie on path '/'. Then in Wordpress (for example), check the cookie, but bypass the check if $_SERVER['REQUEST_URI'] is the excluded URL.
On my shared hosting platform, RewriteRule could not set an environment variable that worked with "Satisfy any".
With any approach, watch out that the page you are protecting does not include images, stylesheets, etc., that trigger an authentication request when the page itself does not.
Add below code to your root htaccess file and don't forget to change your admin url, .htpasswd file page.
<Files "admin.php">
AuthName "Cron auth"
AuthUserFile E:\wamp\www\mg\.htpasswd
AuthType basic
Require valid-user
</Files>
Create .htpasswd file in your root folder and add below username and password (set default username:admin and password: admin123)
admin:$apr1$8.nTvE4f$UirPOK.PQqqfghwANLY47.
Please let me know if you still facing any issue.
None of this worked for me with Apache 2.4, because my PHP/Laravel htaccess did a rewrite and changed Request_URI to be always /index.php.
I used Require expr %{THE_REQUEST} to get the first line of the HTTP request (THE_REQUEST) which remains unchanged.
e.g., "GET /callbacks HTTP/1.1"
This worked for me:
<Location />
AuthType Basic
AuthName "Restricted Content"
AuthUserFile /etc/apache2/.htpasswd
Require expr %{THE_REQUEST} =~ m#^GET /callbacks#
Require valid-user
</Location>
Note you need to change GET to POST if you need to or allow both:
Require expr %{THE_REQUEST} =~ m#^GET /callbacks#
Require expr %{THE_REQUEST} =~ m#^POST /callbacks#
Require valid-user
More about Require expr

.htaccess basic auth by virtual host?

I was wondering if it was possible to setup a conditional http basic auth requirement based on the virtual host URL in an .htaccess file.
For example what I want to do is have mysite.com and test.mysite.com run off the same code base in the same directory but password protect test.mysite.com. It would be setup this way so that I wouldn't need to branch my code since my app code can see which vhost/url it's being served from and pick the database to serve content from.
You can sort of kludge this by using mod_setenvif along with the mod_auth modules. Use the SetEnvIfNoCase directive to set which host is password protected. You'll need a couple of extra directives to satisfy access:
# Check for the hostname here
SetEnvIfNoCase HOST ^test\.mysite\.com\.?(:80)?$ PROTECTED_HOST
Then inside the Directory block (or just out in the open) you have your auth stuff setup, something like this:
AuthUserFile /var/www/test.mysite.com/htpasswd
AuthType Basic
AuthName "Password Protected"
Now for the require/satisfy stuff:
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=!PROTECTED_HOST
This will make it so any host that doesn't match ^test\.mysite\.com\.?(:80)?$ will have access without need for auth (Allow from env=!PROTECTED_HOST) but otherwise, we need a valid user (Require valid-user). The Satisfy any ensures that we just need one of the 2, either the Allow or Require.
I had problems implementing Jon's solution:
Although I am quite familiar with Apache conf and regular expressions, the authentication always fired. From a quick analyzes it looked like the Allow from env=!PROTECTED_HOST line did not kick in.
But I found another solution that actually looks safer to me:
I created two virtual hosts for the two domains pointing to the same document root (which is fully allowed by the way). In one of the vhosts I added the directives for basic auth (directly into the vhost directive block).
Works like a charm. And I have a better feeling that this is really safe - no risk to overlook any details in the regex pattern that would open up the gates for intruders.
<VirtualHost *:80>
ServerName www.mysite.com
DocumentRoot "/path/to/common/doc/root"
<Directory "/path/to/common/doc/root">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName protected.mysite.com
DocumentRoot "/path/to/common/doc/root"
<Directory "/path/to/common/doc/root">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
AuthUserFile /path/to/htpasswd
AuthName "Password please"
AuthType Basic
Require valid-user
</Directory>
</VirtualHost>
Here's a solution similar to what Jon Lin proposed, but using RewriteCond to check the host name:
RewriteEngine On
RewriteCond %{HTTP_HOST} =protected.hostname.com
RewriteRule ^.*$ - [E=DENY:1]
AuthUserFile /path/to/htpasswd
AuthName "Password please"
AuthType Basic
Order Deny,Allow
Satisfy any
Deny from all
Require valid-user
Allow from env=!DENY