# Empiler de multiples backends

Authentification | Utilisateurs | Mot-de-passe
--- | --- | ---
✔ | ✔ |

## Présentation

This backend allows one to chain authentication method, for example to failback to LDAP authentication if Remote authentication failed…

## Configuration

Il faut utiliser `Multiple` comme module d'authentification (celà force `Multiple` pour le module utilisateur). Aller ensuite dans les `paramètres Multiple` pour définir les modules à chaîner pour l'authentification et les utilisateurs. Les modules doivent être séparés par point-virgules/

Par exemple :

    CAS;LDAP

Si CAS échoue, LDAP est utilisé.

Il est possibe d'ajouter une condition. Exemple :

    Remote $ENV{REMOTE_ADDR}=~/^192/;LDAP $ENV{REMOTE_ADDR}!~/^192/'

Multiple essaiera d'utiliser le même module pour l'authentification et les utilisateurs. Exemple, en utilisant “`DBI;LDAP`”, si DBI échoue pour l'authentification, Multi essaie d'utiliser LDAP comme base d'utilisateurs.

### Configuration avancée

Le système `Multiple` peut :

- empiler plusieurs fois le même module avec un nom différent
- surcharger n'importe quel paramètre LL::NG en fonction du backend utilisé

La surcharge n'est pas paramètrable dans le manager

Pour empiler plusieurs fois le même module, utiliser ”#nom” avec différents noms. Exemple :

    LDAP#Openldap; LDAP#ActiveDirectory

Ensuite on peut avoir différents paramètres pour chacun, stockés dans une table de hachage <a1>Perl</a1> nommée multi :

    multi => {
        'LDAP#Openldap' => {
          'ldapServer' => 'ldap1.example.com',
          'LDAPFilter' => '(uid=$user)',
        },
        'LDAP#ActiveDirectory' => {
          'ldapServer' => 'ldaps://ad.example.com',
          'LDAPFilter' => '(&(sAMAccountName=$user)(objectClass=person))',
        }
    },

Cette clef doit être stockée directement dans lemonldap-ng.ini :

    [portal]
    multi = {'LDAP#Openldap'=>{'ldapServer'=>'ldap1.example.com','LDAPFilter'=>'(uid=$user)'},'LDAP#ActiveDirectory'=>{'ldapServer'=>'ldaps://ad.example.com','LDAPFilter'=>'(&(sAMAccountName=$user)(objectClass=person))'}}

## Problèmes connus

### Authentification AuthApache

En utilisant ce module, le portail LL::NG est appelé uniquement si Apache ne retourne pas “401 Authentication required”, aucune bascule n'est donc possible.

Pour outrepasser ceci, suivre la documentation du module AuthApache

### Authentification SSL

Pour chaîner SSL, il est nécessaire de mettre “SSLRequire optional” dans le fichier de configuration Apache, sinon les utilisateurs ne seront authentifiés que par SSL.

### Complex use case

Here is a complex use case involving :

- multiple authentication with
  1. SSL
  2. Kerberos
  3. LDAP
- LemonLDAP::NG as a SAML IdP

The URLs will be:

- https://auth.example.com/kerberos: call to SSL, then Kerberos authentication
- https://auth.example.com/: call to LDAP authentication
- https://auth.example.com/kerberos/saml: official path to SAML request for LemonLDAP::NG IdP. IdP Metadatas contain URL of this form.
- https://auth.example.com/saml: redirected SAML path

In this case, redirection script described in the kerberos configuration page is insufficient. You have to transfer every parameter in SAML request, so rather use this redirection script instead:

    #!/usr/bin/perl
    use CGI ':cgi-lib';
    use strict;
    use MIME::Base64;
    use CGI::Carp 'fatalsToBrowser';

    my $uri = $ENV{"REDIRECT_URL"};
    $uri .= "?".$ENV{"REDIRECT_QUERY_STRING"};
    $uri =~ s/\/kerberos//;
    print CGI::header(-Refresh => '0; URL=https://auth.example.com'.$uri);
    exit(0);

You also have to make LemonLDAP::NG tolerant to the Path in order to have SAML request correctly detected. To do this, go in the manager, and configure the SAML Path (General Parameters > Issuer modules > SAML > Path) with a regular expression:

    ^/(kerberos/saml/|saml/)

Don't forget to configure your authentication modules accordingly. Especially the chained authentications: General Parameters > Authentication parameters > Multi parameters > Authentication stack string

    SSL;Apache;LDAP

Finally, don't forget to configure the portal virtual host with all the authentication parameters needed. Take a special care to the added RewriteRule in the SAML issuer section:

    <VirtualHost "*:443">
        ServerName auth.example.com

        SSLEngine on

        SSLCertificateFile      /etc/httpd/ssl/auth.example.com.crt
        SSLCertificateKeyFile   /etc/httpd/ssl/auth.example.com.key
        SSLCertificateChainFile /etc/httpd/ssl/chain.pem

        SSLVerifyClient optional
        SSLCACertificateFile    /etc/httpd/ssl/ca.crt
        SSLVerifyDepth 10
        SSLOptions +StdEnvVars

        LogLevel warn
        ErrorLog /var/log/httpd/error_log

        # DocumentRoot
        DocumentRoot /var/lib/lemonldap-ng/portal/
        <Directory /var/lib/lemonldap-ng/portal/>
            Require all granted
            Options +ExecCGI +FollowSymLinks
        </Directory>

        Alias /kerberos /var/lib/lemonldap-ng/portal/
        <Location /kerberos>
          Options +execCGI
          ErrorDocument 401 /redirectKRB.pl

          AuthType Kerberos
          KrbMethodNegotiate On
          KrbMethodK5Passwd Off
          AuthName "REALM.COM"
          KrbAuthRealms REALM.COM
          Krb5KeyTab /etc/httpd/keytabs/auth.keytab
          KrbVerifyKDC Off
          KrbServiceName Any
          Require valid-user
        </Location>

    [...]

        # Fournisseur d'identité SAML2
        <IfModule mod_rewrite.c>
            RewriteEngine On
            RewriteRule ^/saml/metadata /metadata.pl
            RewriteRule ^/saml/.* /index.pl
            RewriteRule ^/kerberos/saml/.* /index.pl
        </IfModule>

    [...]
    </VirtualHost>