Do HTTP authentication over HTTPS with URL rewriting

Matthew picture Matthew · Feb 8, 2010 · Viewed 19.8k times · Source

I am trying to protect the ~/public_html/dev directory using http auth basic, but to make that secure I want to run it over ssl.

The middle section of the below .htaccess file switches to https if the request URI begins with /dev and works.

The last section of the file works as well but does not work properly with the https redirect.

I basically want to be able to type http://www.example.com/dev/some_sub_dir/ and be redirected to https://www.example.com/dev/some_sub_dir/ and prompted for the http auth username and password.

What currently happens is if I go to http://www.example.com/dev/some_sub_dir/ I get prompted for a username and password over port 80, and then immediately get prompted again over port 443. So my credentials are being sent twice, once in the clear, and once encrypted. Making the whole https url rewrite a little pointless.

The reason for doing this is so that I won't be able to accidentally submit my user/pass over http; https will always be used to access the /dev directory.

The .htaccess is in the ~/public_html/dev directory.

# Rewrite Rules for example.com
RewriteEngine On
RewriteBase /

# force /dev over https
RewriteCond %{HTTPS} !on
RewriteCond %{REQUEST_URI} ^/dev
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

# do auth
AuthType Basic
AuthName "dev"
AuthUserFile /home/matt/public_html/dev/.htpasswd
Require valid-user

Answer

siliconrockstar picture siliconrockstar · Dec 4, 2012

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...