How to protect some URLs with HTTP authentication using a regex? - regex

I have a public website with an admin area. So I want to protect this admin area using HTTP authentication.
The admin area has this URL: http://mypublicwebsite.com/myadminarea/
myadminareais not a physical directory on my server, there's a routing system based on the requested URL.
Is there an easy way to define that every URL that matches http://mypublicwebsite.com/myadminarea/* must use http authentication?
I've found this answer, but it seems too complicated to me.
Thanks.

You can use it using mod_setenvif and mod_auth. Place this code in your root .htaccess:
SetEnvIfNoCase Request_URI "^/myadminarea" SECURED
AuthType Basic
AuthName "Login Required"
AuthUserFile /full/path/to/passwords
Require valid-user
Order allow,deny
Allow from all
Deny from env=SECURED
Satisfy any
PS: Make sure you create passwords as per Apache manual instructions.

I've just found a solution using the LocationMatch apache directive, to be added in my virtualhost definition:
<VirtualHost *:8080>
...
<LocationMatch "/myadminarea/.*">
AuthType basic
AuthName "Login Required"
AuthUserFile /full/path/to/passwords
Require valid-user
Order allow,deny
Allow from all
</LocationMatch>
</VirtualHost>

Related

Exclude home URL in htaccess authentication

I have a website where I want to allow everyone to view http://localhost:8080/ but password protect all other URLs, for example, http://localhost:8080/home, http://localhost:8080/about, http://localhost:8080/blog-pretty-url, etc.
So far, this is my .htaccess code, but I could only password protect home and about pages, and exclude static files so that the homepage works fine.
SetEnvIf Request_URI (\/(home|about-us)).*(?!(.*(css|js|png|svg|ico|jpg))) auth=1
AuthName "Please login"
AuthType Basic
AuthUserFile "/var/www/html/.htpasswd"
# first, allow everybody
Order Allow,Deny
Satisfy any
Allow from all
Require valid-user
# then, deny only if required
Deny from env=auth
I tried this regex too, but it's not working: (\:\/\/).*(\/\w)(?!(.*(css|js|png|svg|ico|jpg)))
Any help in writing a regex so that it protects all URLs except '/' and excludes static files from the blacklist would be highly appreciated.
sadmansh,
You're on the right track but looking in the wrong direction. This is actually much more simple than it seems. All you need to do is password protect everything and then add a rule to allow all to visit a certain page which in your case is "http://localhost:8080/".
First, password protect every file/directory.
Afterwards, use the following to allow users to visit that particular link you want to give free access to.
Replace "index.html" with the file you would like to share.
<Files "/index.html">
Allow from all
Satisfy any
</Files>
Please let me know if this helps! Have a good one.

Apache DirectoryMatch apply in one subfolder but not in another

i'm trying to apply some rules for a subfolder but not for another subfolder.
I have this
SetEnvIf Referer "((.+\.)?domain\.com|localhost)" localreferer
<DirectoryMatch "/bin(.+/)?">
Require env localreferer
</DirectoryMatch>
And it is working fine. But now I need that this rule does not apply to /bin/public. I will have /bin/private and /bin/public, i need to apply the rule for /bin/private
I tried with
SetEnvIf Referer "((.+\.)?domain\.com|localhost)" localreferer
<DirectoryMatch "/bin/private(.+/)?">
Require env localreferer
</DirectoryMatch>
But all bin's subfolders are allowed from all referer.
What would be the correct regular expression to allow /bin/public to be accessed from any referer and /bin/private only from the ones I have on the list
Thanks in advance
i found the issue and the solution. i need to use LocationMatch instead of DirectoryMatch, so
SetEnvIf Referer "((.+\.)?domain\.com|localhost)" localreferer
<LocationMatch "/bin(.+/)?">
Require env localreferer
</LocationMatch>
<LocationMatch "/bin/public(.+/)?">
Require all granted
</LocationMatch>

Django Invalid HTTP_HOST header on Apache - fix using Require?

A couple weeks ago, I had a wonderful time setting up an Apache and Django configuration to work while forcing SSL and operating behind an AWS load balancer.
Now that it is all working nicely, I'm still constantly receiving the common "Invalid HTTP_HOST header" error, and trying to figure out the right way to go about fixing it.
Searching has brought me to the following answer regarding the Apache configuration:
How to disable Django's invalid HTTP_HOST error?
Which recommends placing the following settings inside the <Directory></Directory> block in the VirtualHost file:
SetEnvIfNoCase Host .+ VALID_HOST
Order Deny,Allow
Deny from All
Allow from env=VALID_HOST}
This works, but according to Apache (https://httpd.apache.org/docs/2.4/howto/access.html) this method is deprecated.
I've read through the Apache docs but when I tried using the following code it just shut down access to the site and gave me a "Not Authorized" error.
<RequireAll>
Require host example.org
</RequireAll>
Not entirely sure what I'm missing. I know I can solve the problem using the first answer, just trying to figure out the "right" way using code that isn't deprecated. Site is using WSGIDaemonProcess to run the Django App and has the following set to force the SSL through AWS
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTP:X-Forwarded-For} !=""
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
No need to use mod_setenvif as HTTP_HOST is already a variable and you can evaluate it directly.
<Directory /var/www/html/>
Require expr %{HTTP_HOST} == "example.com"
Options
</Directory>
So, after messing with this for a long time I figured out that the problem I was dealing with may have something to do with the hostname reverse DNS lookup failing, since the IP address was pointing to an AWS EC2 instance instead of my domain.
After finally giving up on getting it right I returned to the post on how to disable the log error, and tried using the env variable, which seems to be working.
Apparently the correct format for Require is:
<Directory /var/www/html/>
SetEnvIfNoCase Host example\.com VALID_HOST
Require env VALID_HOST
Options
</Directory>
These guys had it right, just need to update it for the current "Require" directive.
How to disable Django's invalid HTTP_HOST error?

Can I use a regex or string replace with Apache VirtualDocumentRoot?

I have an Apache configuration which is something like this:
<VirtualHost *:80>
ServerAlias *.example.com
VirtualDocumentRoot /var/www/%1
<Directory /var/www/>
Options -Indexes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
The idea is that it serves any subdomain request from a directory with the same name. For instance, the docroot for http://beta-a.example.com becomes /var/www/beta-a.
This works fine.
My question is this: Is there any way to modify the extracted part of the request based on some logic? Ideally a regex. For example, I'd like to take all requests like:
http://beta-a.example.com
http://beta-b.example.com
http://beta-c.example.com
And remove everything after and including the - so that the docroot would become /var/www/beta. Basically, I'd like to find some way to have alternate host names that get served from the same docroot. I know of the rule:
%N.M insert (part of) the name
But this requires that I specify an explicit length and does not seem to allow any application of logic for the extracted substring.
Although not exactly what I am looking for, I'll offer a workaround which I'm using here. I can add an additional subdomain in the second position which accomplishes almost the same thing. So using these:
http://beta.a.example.com
http://beta.b.example.com
http://beta.c.example.com
All the above will be served from docroot /var/www/beta.

Determine HTTPS in htaccess to Set Environment

I want to redirect the user to the authentication page only if the request is 'https'.
Currently I have written the following in my .htaccess file to do the same, but it doesn't work.
SetEnvIf Request_Protocol ^HTTPS.* IS_HTTPS
AuthType shibboleth
AuthName "Login"
ShibRequireSession on
require user abcd
Allow from env=IS_HTTPS
Is the regex for determining HTTPS correct? Earlier I had the SetEnvIf statement as follows. This too didn't work.
SetEnvIf %{SERVER_PORT} ^80$ IS_NON_SSL
AuthType shibboleth
AuthName "Login"
ShibRequireSession on
require user abcd
Allow from env=!IS_NON_SSL
But as per the documentation for SetEnvIf directive (http://httpd.apache.org/docs/2.2/mod/mod_setenvif.html), the SERVER_PORT variable is not available.
I don’t think that the value Request_Protocol can be used to determine this – according to the docs page you linked, that contains something like (e.g., "HTTP/0.9", "HTTP/1.1", etc.) – so the protocol itself will always be HTTP; and that makes sense, as HTTPS is not a real “protocol”, but only the common name for HTTP with TLS “wrapped around it”, on the OSI level below it (6).
I’m not sure about the actual order of request processing (and don’t know where to find it right now off the top of my head) – but maybe you could combine this with mod_rewrite to achieve what you want? A RewriteCond is able to check whether HTTPS is used by checking the variable HTTPS for the value on – and a RewriteRule following that condition could set an environment variable for you using the [E] flag – something like this:
RewriteCond %{HTTPS} ^on$
RewriteRule . - [E=IS_HTTPS]
This will set the environment variable IS_HTTPS with an empty value, but that should be enough to check it with Allow from env=IS_HTTPS.
Mind giving this a try? As I said, I’m not sure if this will work because of processing order – but tryin’ cost nuffin, right?
You can try:
SetEnvIf Request_Protocol ^HTTPS.* IS_HTTPS
AuthType shibboleth
AuthName "Login"
ShibRequireSession on
require user abcd
Satisfy any
Order deny,allow
Deny from all
Allow from env=IS_HTTPS