Do HTTP authentication over HTTPS with URL rewriting
There is a relatively popular hack to force HTTPS before doing Basic Authentication. I first saw it here:
http://blog.jozjan.net/2008/02/htaccess-redirect-to-ssl-https-before.html
It involves using a custom error document to handle whatever happens after the HTTPS check fails.
For example, I have a single page I need to force HTTPS on, so I did this in an .htaccess file:
<FilesMatch "secure-page.php"> SSLRequireSSL ErrorDocument 403 https://www.example.com/secure-page.php AuthType Basic AuthName "Secure Page" AuthUserFile /var/www/whatever/.htpasswdFile Require valid-user</FilesMatch>
Which translates to:
if the requested page is 'secure-page.php' - if not HTTPS, then redirect to a custom 'error page' - the 'error page' is actually just the HTTPS version of the page - on the second request, since the HTTPS check now passes, perform Basic Auth :)
You can extend this concept to a directory or other use cases - your custom 'error page' could be a php page that redirects to the correct HTTPS URL, or a CGI script like in the link above...
I ran into the same problem and finally found an ugly solution, but it works. Put the rewrite rule in a Directory directive in httpd.conf or one of your conf.d files (i.e., in the "Main" server configuration). Then, put the Auth* and Require lines in a Directory directive inside the <VirtualHost _default_:443>
container in ssl.conf (or wherever your SSL VirtualHost is defined).
For me, this means creating a file /etc/httpd/conf.d/test.conf
with:
<Directory "/var/www/html/test"> # # force HTTPS # RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}</Directory>
...and then adding the following inside /etc/httpd/conf.d/ssl.conf
just above the </VirtualHost>
tag:
<Directory "/var/www/html/test"> # # require authentication # AuthType Basic AuthName "Please Log In" AuthUserFile /var/www/auth/passwords Require valid-user</Directory>
Doing this makes Apache apply the RewriteRule to all requests, and the auth requirements only to requests in the 443 VirtualHost.
Building on siliconrockstar's answer, I am adding a php script that would work in the case where you want to force SSL on all the files, not just the one-file case shown by siliconrockstar. Here again it works in conjunction with the htaccess file.
The htaccess to protect to whole directory:
SSLRequireSSL ErrorDocument 403 /yourphp.php AuthType Basic AuthName "Secure Page" AuthUserFile /some_path_above_the_html_root/.htpasswdFile Require valid-user
The php called by the htaccess (the path given for the php in this sample htaccess is the root of your site), which forces https on the url you called:
<?php$path = "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];if ( $_SERVER['SERVER_PORT'] == 80) { header("Status: 302 Moved\n"); header("Location: ".$path."\n\n");}else { header( "Content-type: text/html\n\n"); echo "How did you get here???";}?>
If your site doesn't have an SSL certificate, you'll have to install one. If this is your only use for it, you can install a self-signed certificate. On a cPanel VPS with your site on a dedicated IP, that takes moments to do: in WHM, visit
One. Generate an SSL Certificate and Signing Request
then
Two. Install an SSL Certificate on a Domain