Saturday, April 13, 2013

htaccess Rewrite before Authentication - HTTP to HTTPS

Error

When having an "htaccess" file which contains "Rewrite" then "Authentication" the Authentication is done before the rewrite 

This happenes when you need to make sure the user is authenticating on HTTPS instead of HTTP so you need to do the rewrite before the HTTP Basic Authentication


RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}



AuthType Basic
AuthName "protected area"
AuthUserFile /FILE_PATH
Require user USER


Solution

There are 2 solutions for Apache 2.2 installations


Solution #1 - Easiest

Just enclose the authentication by a <FilesMatch "."> block

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}


<FilesMatch ".">

AuthType Basic
AuthName "protected area"
AuthUserFile /FILE_PATH
Require user USER

</FilesMatch>


Solution #2

Require SSL and point the error document to a file which redirects to HTTPS

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

SSLRequireSSL
ErrorDocument 403 /PATH_TO_A_PAGE_TO_REDIRECT_TO_HTTPS


AuthType Basic
AuthName "protected area"
AuthUserFile /FILE_PATH
Require user USER





5 comments:

  1. If you are using Apache 2.4, you can use the configuration section:

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}


    AuthType basic
    AuthName "Private"
    AuthUserFile /path/to/passwordfile
    Require valid-user


    The configuration section was introduced in Apache 2.4 and it can be used to only perform authentication when using HTTPS protocol.

    ReplyDelete
  2. That should be:

    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

    <If "%{HTTPS} == 'on'">
    AuthType basic
    AuthName "Private"
    AuthUserFile /path/to/passwordfile
    Require valid-user
    </If>

    ReplyDelete
    Replies
    1. Thank you Anonnymous! ;-) Although the above worked, an ending slash was required to force ssl/https. Your solution with worked great! Thanks again!

      Delete
    2. Thank you for pointing this out! I thought Karim Ouda's solution was not working until I added the ending slash. But with the If statement, the ending slash is not required. Awesome guys!

      Delete
  3. The first solution is simple, elegant and works for apache 2.2.
    Karim You saved the day!

    ReplyDelete