Reputation: 2644
This is my .htaccess:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
AuthUserFile /etc/hi
AuthName "hi"
AuthType Basic
require valid-user
It asks for user authentication using http, meaning that password will be sent in plain text. It will than redirect to the https version and ask the password again.
How can i fix it?
Upvotes: 31
Views: 32105
Reputation: 7748
Here is the only solution that worked in one of my configurations:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
<If "%{SERVER_PORT} != '80'">
AuthUserFile /etc/hi
AuthName "hi"
AuthType Basic
require valid-user
</If>
Notably, this is for an Apache 2.4 over which I have no control (shared hosting). It seems that the %{HTTPS}
variable is not defined on this config, and any solution based on SSLRequireSSL
generated a 500 Internal Server Error.
(Side note: In case you prefer a 403 Forbidden instead of a 301 Permanent Redirect when serving HTTP requests, use RewriteRule ^(.*)$ - [F,L]
instead)
Upvotes: 2
Reputation: 21
None of the above worked for me, but this did. My only concern is if there are certain conditions whereby the auth is not triggered allowing someone access without the credentials. I'm not sure there are, but maybe you bright people may say otherwise.
This code redirects non-www to www and http to https, with .htaccess folder auth.
This is the contents of the htaccess file in the directory you want to protect:
RewriteEngine on
# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/foldername/$1 [L,R=301]
# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/foldername/$1 [L,R=301]
# Apache 2.4 If
<If "%{HTTPS} == 'on' && %{HTTP_HOST} =~ /www/">
AuthType Basic
AuthName "Protected folder"
AuthUserFile "/home/etc/.htpasswds/public_html/foldername/passwd"
require valid-user
</If>
Upvotes: 2
Reputation: 6579
If you're running Apache 2.4 you can use configuration sections to solve this quite easily.
Eg...
# Redirect to HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# Authenticate users only when using HTTPS
# Enable for <v2.4
# SSLRequireSSL
# ErrorDocument 403 /secure-folder/
# Enable for >v2.4
<If "%{HTTPS} == 'on'">
AuthType Basic
AuthName "Special things"
AuthUserFile /etc/blah.htpasswd
# Prevent this 'Require' directive from overriding any merged previously
<IfVersion >= 2.4>
AuthMerging And
</IfVersion>
Require valid-user
# Enable for >v2.4
</If>
Upvotes: 24
Reputation: 29019
The checked solution https://stackoverflow.com/a/15940387/2311074 does work on Firefox on Ubuntu 16.04, but it does not work on Firefox on Win 7.
If you want to protect your folder https://yourdomain.com/securefolder
then you need to create in that folder a .htaccess
with the following content:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
SSLRequireSSL
ErrorDocument 403 https://yourdomain.com/securefolder
AuthType Basic
AuthName "Admin"
AuthUserFile /outside/your/www/folder/.htpasswd
Require user admin Admin
The way it works is that when you are calling the website through http://
instead of https://
it will redirect you to the error page. The trick is to use the correct link with the https://
as your default error page.
Upvotes: 4
Reputation: 16899
Our client's webapp is installed in his webuser directory. Authorisation is handled before mod_rewrite rules (https://serverfault.com/a/443185/253111), and we could not get the accepted answer to work, so mod_rewrite seemed not an option.
Eventually we explicitly required SSL and used the webapp's root over HTTPS as 403 and 404 error documents. So when one visits any page over HTTP (which is unauthorized, hence the 403) or a non existing page (404), he is being redirected to ie. https://DOMAIN.TLD/~WEBUSER/admin.
This is the .htaccess file with some extra info in the comments.
### INFO: Rewrites and redirects are handled after authorisation
### @link https://serverfault.com/a/443185/253111
### INFO: Log out of a HTPASSWD session
### This was not always possible, but Firefox and Chrome seem to end sessions
### when a new one is trying to be using ie.:
### https://logout:[email protected]/~WEBUSER/
### @link http://stackoverflow.com/a/1163884/328272
### FORCE SSL: Explicitly require the SSL certificate of a certain domain to
### disallow unsigned certificates, etc. ErrorDocument commands are used to
### redirect the user to an HTTPS URL.
### @link http://forum.powweb.com/showthread.php?t=61566
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "DOMAIN.TLD"
### HTPASSWD AUTHENTICATION
AuthUserFile /var/www/vhosts/DOMAIN.TLD/web_users/WEBUSER/.htpasswd
AuthType Basic
AuthName "Hello"
Require valid-user
### ERROR DOCUMENTS: Redirect user in case of a 403 / 404.
ErrorDocument 403 https://DOMAIN.TLD/~WEBUSER/admin
ErrorDocument 404 https://DOMAIN.TLD/~WEBUSER/admin
Upvotes: 2
Reputation: 307
I'm running Apache 2.2 and none of the above solutions worked for me. I found a workaround for me here. Basically, you need to set SSLRequireSSL and use some script language in the ErrorDocument to forward users to HTTPS. Unfortunately, in my case this only works when accessing particular files on the server, it does NOT work if just the domain is provided. Here is what I did:
AuthType Basic
AuthName "Password Protected Area"
AuthUserFile /my/path/to/.htpasswd
#Require valid-user
<FilesMatch "(^(?!ssl.php).*)">
SSLRequireSSL
ErrorDocument 403 /ssl.php
Require valid-user
</FilesMatch>
The regex in FileMatch tells apache to SSLRequireSSL for all files except ssl.php - and forward the user to ssl.php if he tries to access without SSL.
My ssl.php looks like this:
if(!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == "" || $_SERVER['HTTPS'] == "off")
{
$redirect = "https://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
header("HTTP/1.1 301 Moved Permanently");
header("Location: $redirect");
exit;
}
What now happens:
The last point is what I am not happy with, if someone has a solution for that, I'd be glad to hear about it. Things I tried to solve this issue:
Upvotes: 2
Reputation: 129
Thank you very much, Istador!
My Apache is of version 2.2 (Synology NAS DSM 5.1) so these two do not work on it:
RewriteOptions Inherit
IfVersion
After taking them (and the section of version >= 2.4) out. The whole thing began to work for me.
There are a lot suggestions out there for this topic, I spent two days to try them out.
But only this one works for me.
Here's what I did:
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
AuthType Basic
AuthName "private area"
AuthUserFile /path/to/file/.htdigest
Order Deny,Allow
Deny from all
Satisfy Any
Allow from env=!HTTPS
Require valid-user
So it's verified to work on Apache 2.2, Synology DSM 5.1.
Upvotes: 12
Reputation: 173
Molomby's solution works in 2.4 and higher, but doesn't work with the current Debian version 2.2.22.
Ben's / Chris Heald's solutions also didn't work for me in 2.2.22, but that was due to a different order/satisfy configuration. These settings have changed with 2.4 and the solution seems to be incompatible with 2.4 and above (the redirect works, but the browser is just displaying an unauthorized error without asking for credentials).
Here is a combination of both solutions that should work for versions below and above 2.4:
RewriteEngine on
RewriteOptions Inherit # rewrite rules from parent directories
RewriteCond %{HTTPS} off
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
AuthType Digest
AuthName "private area"
AuthDigestProvider file
AuthUserFile /path/to/file/.htdigest
<IfVersion < 2.4>
Order Deny,Allow
Deny from all
Satisfy Any # reset this to 'All' in custom <Files> and <Directory> directives that block access
Allow from env=!HTTPS
Require valid-user
</IfVersion>
<IfVersion >= 2.4>
<If "%{HTTPS} == 'on'">
AuthMerging And
Require valid-user
</If>
</IfVersion>
Requirements: mod_rewrite, mod_auth, mod_digest, mod_version
Upvotes: 1
Reputation: 252
I get around it this way. Just allow Non-SSL since it will be redirected then require auth once on SSL...
SetEnvIf %{SERVER_PORT} ^80$ IS_NON_SSL
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
AuthUserFile /etc/hi
AuthName "hi"
AuthType Basic
require valid-user
Allow from env=IS_NON_SSL
Upvotes: 17