Search code examples
apachemod-rewriteapache2http-authentication

apache rewrite before authentication of location


I'm trying to configure an Apache webserver to work the following way:

if /specialdir/ -> no password check, no hostname check, no https redirect.
if 192.168.1.1 url -> redirect to https://hostname, do password check
if http://hostname/ -> redirect to https://hostname/, do password check
if '/' is requested -> redirect to https://hostname/entry/, do password check 

So in summary, all URLs, except specialdir should always be visited via https://hostname with a mandatory authentication.

I'm currently using the following configure in httpd.conf and everything works, except that authentication occurs twice: once for the http connection and a second time for the https connection. Somehow my configuration doesn't do the redirect first.

(yes, I'm aware that using Location is considered to not be ideal, however, this way seems to be easier to enforce the same configuration for all urls / directories (since I only have one exception)).

<Location />
    ## authentication
    AuthBasicProvider file ldap
    AuthUserFile /etc/apache2/.htpasswd
    AuthGroupFile /dev/null
    AuthType Basic
    # allow alternative authentication, here "file"    
    AuthzLDAPAuthoritative off
    AuthName "Login required"
    AuthLDAPURL "ldap://xxx?sAMAccountName" NONE
    AuthLDAPBindDN "xxx" 
    AuthLDAPBindPassword xxx
    require valid-user

    ## redirects
    Options +FollowSymLinks
    RewriteEngine On
    # in case /specialdir/ is requested - go there right away and
    # skip remaining checks.
    RewriteCond %{REQUEST_URI} "/specialdir/"
    RewriteRule (.*) $1 [L]
    # someone trying to access the host by IP - redirect to hostname.com
    RewriteCond %{HTTP_HOST} !^hostname.com [NC]
    RewriteRule (.*) https://hostname.com%{REQUEST_URI} [R=301,L]
    # https is off? redirect to https (because we are transmitting passwords)
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://hostname.com%{REQUEST_URI}
    # no directory requested - go to 'entry'.
    RedirectMatch ^/$ /entry/
</Location>


## allow unrestricted access to the following resources
<Directory /var/www/specialdir>
    # All access controls and authentication are disabled
    # in this directory
    Satisfy Any
    Allow from all 
</Directory>

Solution

  • If you have access to the server config files, you could just separate the HTTP and HTTPS parts into 2 separate vhost configs (or separate them into 2 separate blocks in your httpd.conf):

    • the HTTP vhost either serves /specialdir/ or redirects to HTTPS
    • the HTTPS vhost requires authentication.

    So something like this in your http vhost config:

    Options +FollowSymLinks
    
    RedirectMatch ^/$ https://hostname.com/entry/
    
    RewriteEngine On
    RewriteCond %{REQUEST_URI} !^/specialdir/
    RewriteRule .* https://hostname.com%{REQUEST_URI} [R,L]
    
    # maybe include your directory directive here as well
    <Directory /var/www/specialdir>
        # All access controls and authentication are disabled
        # in this directory
        Satisfy Any
        Allow from all 
    </Directory>
    

    And the https vhost would just have all your auth stuff in it.