Implementing Multiple Authentication Methods for Apache VirtualHost: CAS, OpenID and Digest Auth


10 views

When securing web applications, we often need to support multiple authentication mechanisms simultaneously. Apache's modular architecture allows this through different auth-type modules, but configuring them for the same Location requires careful handling.

The key is using Require directives with logical operators to combine authentication methods. Here's a base configuration structure:


<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/html
    
    <Location "/secure">
        # CAS Authentication
        AuthType CAS
        CASScope /
        CASLoginURL https://cas.example.com/login
        CASValidateURL https://cas.example.com/serviceValidate
        
        # OpenID Connect
        AuthType openid-connect
        OIDCProviderMetadataURL https://oidc.example.com/.well-known/openid-configuration
        OIDCClientID your_client_id
        OIDCClientSecret your_secret
        
        # Digest Authentication
        AuthType Digest
        AuthName "Restricted Area"
        AuthDigestDomain /secure/
        AuthDigestProvider file
        AuthUserFile /etc/apache2/digest-passwords
        
        # Combined requirement
        Require valid-user
    </Location>
</VirtualHost>

Ensure all required modules are loaded in your Apache configuration:


LoadModule auth_cas_module modules/mod_auth_cas.so
LoadModule auth_openidc_module modules/mod_auth_openidc.so
LoadModule auth_digest_module modules/mod_auth_digest.so

When multiple auth types are specified, Apache will attempt them in order until one succeeds. You can control this behavior:


<Location "/secure">
    # Primary auth method
    AuthType openid-connect
    # Fallback methods
    <If "%{REMOTE_USER} == ''">
        AuthType Digest
    </If>
    <If "%{REMOTE_USER} == ''">
        AuthType CAS
    </If>
    Require valid-user
</Location>

Watch for these potential problems:

  • Module conflicts when multiple auth modules modify the same headers
  • Session cookie collisions between different auth methods
  • Different logout handling requirements for each auth type

For more complex scenarios, you can use <If> conditions to select auth methods:


<Location "/secure">
    <If "%{HTTP_USER_AGENT} =~ /Mobile/">
        AuthType openid-connect
        OIDCRedirectURI https://example.com/secure/redirect_uri
    </If>
    <Else>
        AuthType Digest
        AuthDigestProvider file
        AuthUserFile /etc/apache2/digest-passwords
    </Else>
    Require valid-user
</Location>

When securing web applications, we often need to support multiple authentication mechanisms simultaneously. Apache's modular architecture allows this through different auth modules, but configuring them to work together requires careful setup.

The key is using Satisfy any directive combined with proper Require statements for each auth type. Here's a basic structure:


<Location "/protected">
    # General auth control
    AuthType Basic
    AuthName "Protected Area"
    Satisfy any
    
    # CAS configuration
    <IfModule mod_auth_cas.c>
        CASCookiePath /tmp/
        CASLoginURL https://cas.example.com/login
        CASValidateURL https://cas.example.com/serviceValidate
        Require valid-user
    </IfModule>
    
    # OpenID configuration
    <IfModule mod_auth_openid.c>
        AuthOpenIDDBLocation /var/cache/apache2/openid.db
        Require valid-user
    </IfModule>
    
    # Digest auth configuration
    <IfModule mod_auth_digest.c>
        AuthDigestProvider file
        AuthUserFile "/etc/apache2/users.digest"
        Require valid-user
    </IfModule>
</Location>

When combining multiple auth methods:

  • Ensure all required modules are loaded (a2enmod for Debian-based systems)
  • Module loading order matters - some auth modules may conflict
  • Test each auth method independently first

For more complex scenarios with fallback mechanisms:


<Location "/api">
    AuthType Basic
    AuthName "API Access"
    Satisfy any
    
    # Primary CAS auth
    <IfModule mod_auth_cas.c>
        CASScope /
        CASAuthNHeader On
        Require cas-role admin
    </IfModule>
    
    # Fallback to OpenID
    <IfModule mod_auth_openid.c>
        AuthOpenIDAXRequire email @example\.com$
        Require openid-user
    </IfModule>
    
    # Emergency basic auth
    <IfModule mod_auth_basic.c>
        AuthBasicProvider file
        AuthUserFile "/etc/apache2/emergency.htpasswd"
        Require user admin
    </IfModule>
</Location>

Common issues and solutions:

  • Module conflicts: Check error logs for authentication loop messages
  • Header collisions: Some modules modify the same headers - use CASAllowWildcardCert off if needed
  • Performance impact: Multiple auth checks increase latency - consider caching