1

For testing purposes, I have a password-protected clone of my website, accessible using a subdomain such as dev.example.com. I am using basic authentication, and all traffic should be transferred using https. Hence, any requests using http must be redirected to https before authentication. I have tried the following .htaccess file.

RewriteEngine On

# Rewrite any requests to ip addresses or *.example.com to dev.example.com
RewriteCond %{HTTP_HOST} !^dev\.example\.com$ [NC]
RewriteCond %{THE_REQUEST} \s(\S*)\s
RewriteRule ^ https://dev.example.com%1 [L,NE,R=302]

# Rewrite to https
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]

# Require authentication
AuthName "Restricted development environment"
AuthType Basic
AuthUserFile /var/www/html/.htpasswd
Require valid-user

I'm checking both %{HTTPS} and %{HTTP:X-Forwarded-Proto} to support both the case when the client is connecting the server directly, and also the case when the server is behind a load balancer, and the traffic between the load balancer and the server is using http.

The idea is that the [L] flag should cause the redirects to happen before authentication, but this does not seem to be the case. When accessing http://dev.example.com, authentication pops up. If I enter the credentials correctly, I'm redirected to https://dev.example.com, and authentication pops up again.

I found this similar question, where the [L] flag is not used. The suggested solution there is to set an environment variable when https is in use, and only allow access when that variable is set. But I don't understand why I can't just use the [L] flag instead. Maybe I've misunderstood it's use and meaning. Why isn't the redirect done before authentication when using the [L] flag?

Magnar Myrtveit
  • 2,432
  • 3
  • 30
  • 51
  • You have misunderstood `L` flag. `L` flag only acts like `continue` in a loop. It just forces `mod_rewrite` loop to run again. Besides authentication is done using `mod_auth_basic` that is totally independent of `L` flag. – anubhava Sep 15 '17 at 09:27
  • Thanks, @anubhava. From the documentation: "Use this flag to indicate that the current rule should be applied immediately without considering further rules." To me this sounds like a 302 redirect should be done immediately when a `[L,R=302]`-rule matches, and the auth-section not be reached until after the redirect? – Magnar Myrtveit Sep 15 '17 at 09:33
  • auth section is from a different module hence `L` flag or any `mod_rewrite` flag won't prevent it from executing. It might also happen that auth section executes first before `mod_rewrite` module. – anubhava Sep 15 '17 at 09:53
  • Only way these modules communicate with each other is by using env variables in `allow from` or `deny from` directives. – anubhava Sep 15 '17 at 13:38

1 Answers1

2

It seems that the different Apache modules work independently, and the [L] flag does not prevent authentication from happening, despite the documentation saying Use this flag to indicate that the current rule should be applied immediately without considering further rules.

I ended up with wrapping the authentication in an If directive checking that the connection is secure.

If the connection is not secure, authentication is not performed, and the request is redirected. After the redirect, the connection is secure, and authentication is performed.

# Require authentication
# If the connection is not secure, authentication is postponed
<If "%{HTTPS} = 'on' || %{HTTP:X-Forwarded-Proto} = 'https'">
   AuthName "Restricted development environment"
   AuthType Basic
   AuthUserFile /var/www/html/.htpasswd
   Require valid-user
</If>
Magnar Myrtveit
  • 2,432
  • 3
  • 30
  • 51