libertempo / web

Application web de gestion des congés en ligne
GNU General Public License v2.0
67 stars 63 forks source link

SSO Microsoft #74

Closed Matou25 closed 8 years ago

Matou25 commented 8 years ago

Bonjour,

est 'il prevu d'ajouter une fonction SSO pour l'authentification dans libertempo. le but est que le navigateur envoi l'identifiant et mot de passe de la session windows Actuellement j'utilise cela avec Glpi: le nom du serveur est dans la zone intranet de IE dans firefox about config j'ai ajouter : network.automatic-ntlm-auth.trusted-uris;-> mon domaine interne pour chrome c'est natif, il n'y a rien a faire

dans le apache.conf j'ajoute une virtual dir

DocumentRoot /usr/share/glpi ServerName glpi.domaineinterne.tld AuthType Kerberos AuthName "Login" KrbServiceName HTTP/glpi.mondomaine.fr@mondomaine.fr # KrbServiceName HTTP ``` KrbVerifyKDC on KrbMethodNegotiate on KrbMethodK5Passwd on KrbAuthRealms mondomaine.fr Krb5KeyTab /etc/apache2/keytab/chronos2.keytab require valid-user ```

j'ai suivi ceci: http://www.cymea.net/sso-apache2-active-direcotry-powerbroker-identity-services/

d'apres ce que j'ai compris le login est mot de passe sont passé en paramètre a l'ouverture de la page glpi.

je vais faire plus de recherche pour mieux comprendre le mecanisme.

wouldsmina commented 8 years ago

Ok c'est kerberos. Ca utilise l'authentification par http. Reste a savoir comment kerberos confirme que le login/pw est ok -> envoyé le «ok» et le login a Libertempo... Après ce sera simple a gérer dans libertempo (de la même manière que CAS en fait).

Matou25 commented 8 years ago

bonjour,

pour que cela fonctionne dans glpi, j'ai activer "Autre authentification transmise dans la requête HTTP" Champs de stockage de l'identifiant dans la requête HTTP : REMOTE_USER

Supprimer le domaine des identifiants de la forme identifiant@domaine -> oui

Matou25 commented 8 years ago

si ca peu aider, pour verifier que mon navigateur envoi bien les infos j'utilise une page php qui contient : <?php

$user = $_SERVER["REMOTE_USER"]; $ServerGLPI = $_SERVER["HTTP_HOST"]; echo "identifiant : $user"; echo "
ServerGLPI : $ServerGLPI";

$cred = explode("\",$_SERVER["REMOTE_USER"]); if(count($cred)==1) array_unshift($cred, "(no domain info - perhaps SSPIOmitDomain is On)"); list ($domain,$user) = $cred;

echo "

You appear to be user : $user
"; echo "logged into the Windows NT domain : $domain";

/_echo "login : "; echo $_SERVER["REMOTEUSER"];/ ?>

wouldsmina commented 8 years ago

Oui c'est pas mal cette exemple. Pour etre sur de bien comprendre, avec ce mécanisme tu n'as pas besoin de saisir tes identifiants lorsque tu va sur glpi. C'est kerberos qui se charge de lier ton compte AD a l'appli. C'est bien ca?

Matou25 commented 8 years ago

oui c'est bien ca :-)

wouldsmina commented 8 years ago

Si tu veux, tu peux essayer ca :

dans include/fonction.php ajoute :

function authentification_AD_SSO() {
$cred = explode("\",$_SERVER["REMOTE_USER"]);
if(count($cred)==1)
    $userAD = $cred[0];
else
    $userAD = $cred[1]

    session_create($userAD);

    //ON VERIFIE ICI QUE L'UTILISATEUR EST DEJA ENREGISTRE SOUS DBCONGES
    $req_conges = 'SELECT u_login FROM conges_users WHERE u_login=\''. SQL::quote($userAD).'\'';
    $res_conges = SQL::query($req_conges) ;
    $num_row_conges = $res_conges->num_rows;
    if($num_row_conges !=0)
        return $userAD;

    return '';

dans le fichier index.php ligne 98 remplace :

$usernameCAS = authentification_passwd_conges_CAS();

par

$usernameCAS = authentification_AD_SSO();

Pour finir active, dans la config de Libertempo, l'authentification par CAS.

Je me demande quand même si c'est bien secure tout ça, as tu des infos as ce sujet? Et comment se comporte cette authentification avec un compte local (hors AD)?

wouldsmina commented 8 years ago

J'ai cherché un peu d'information sur la sécurité de se mode d'authentification. Ça marche comme CAS (c'est même compatible), ça me rassure, je pensais bêtement que c'était le poste local qui transmettait directement le login. Pour info : le poste transmet un ticket au navigateur, celui ci le transmet au serveur, pour vérification, qui retourne le login si le ticket est valide.

Matou25 commented 8 years ago

salut,

merci pour l'info j'étais en train de chercher de mon coté, je pensais a un truc comme ça car si on publie le site sur le net cela ne fonctionne pas sauf en ajoutant un vpn vers le réseaux dans lequel il y a l'annuaire.

wouldsmina commented 8 years ago

Salut @matou25, As tu réussi à utiliser l'authentification par kerberos?

Matou25 commented 8 years ago

Salut et meilleurs vœux pour cette année 2016,

j'ai testé en décembre mais ça ne fonctionnait pas, j'ai attendu que le compta importe tout les utilisateurs, je viens de retester mais ce n'est pas mieux. impossible d’accéder a la page de login ni aucune autre. j'ai une erreur appache: [Thu Jan 21 11:25:28.763664 2016] [:error] [pid 9981] [client 192.168.10.93:65020] PHP Parse error: syntax error, unexpected 'if' (T_IF) in /usr/share/libertempo/index.php on line 100

voila la ligne 100: // Si CAS alors on utilise le login CAS pour la session if ( $_SESSION['config']['how_to_connect_user'] == "cas" && $session_username != "admin" && ( $session_username != "conges" || !$_SESSION['config']['responsable_virtuel'] ) ) { //redirection vers l'url d'authentification CAS $usernameCAS = authentification_AD_SSO(); ligne 100 if($usernameCAS != "") { session_create($usernameCAS); } else //dans ce cas l'utilisateur n'a pas encore été enregistré dans la base de données db_conges { header_error();

        echo  _('session_pas_de_compte_dans_dbconges') ."<br>\n";
        echo  _('session_contactez_admin') ."\n";

        $URL_ACCUEIL_CONGES=$_SESSION['config']['URL_ACCUEIL_CONGES'];
        deconnexion_CAS($URL_ACCUEIL_CONGES);
        bottom();
        exit;
    }
}
else 
{
Matou25 commented 8 years ago

erreur de ma part il manquait le ; ligne 99 même si il apparait en mon post juste au dessus , je n'avais pas validé la modif du fichier. $usernameCAS = authentification_AD_SSO();

Matou25 commented 8 years ago

maintenant : [Thu Jan 21 15:58:27.293712 2016] [:error] [pid 9982] [client 192.168.10.93:64267] PHP Parse error: syntax error, unexpected '"', expecting identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in /usr/share/libertempo/include/fonction.php on line 421

je cherches

wouldsmina commented 8 years ago

Bonne année 2016,

Tu as modifié un truc dans include/fonction.php?

Matou25 commented 8 years ago

salut,

oui j'ai fait quelques modif, il me reste un soucis avec le fichier keytab, des que j'ai fini je te détaille les modif et la démarche de mise en place.

Matou25 commented 8 years ago

Salut,

ça y a est tout fonctionne, j'ai glpi et libertempo sur le même serveur avec liaison ldap et sso fonctionnel.

donc voila les modificatifs dans /include/fonction.php 1- j'ai mis en commentaire les lignes 343 à 418 car j'ai des erreurs a cause du if($connexionCAS!="active") en effet l'authentification CAS est activée dans la config mais il manque des paramètres. 2- j'ai ensuite modifié la fonction que tu m'as donné plus haut au niveau de la fonction explode pour découpé le login qui est de la forme nom@domain.tld et non domain\nom.

function authentification_AD_SSO() { $cred = explode("@",$_SERVER["REMOTE_USER"]); if(count($cred)==1) $userAD = $cred[1]; else $userAD = $cred[0];

session_create($userAD);

//ON VERIFIE ICI QUE L'UTILISATEUR EST DEJA ENREGISTRE SOUS DBCONGES
$req_conges = 'SELECT u_login FROM conges_users WHERE u_login=\''. SQL::quote($userAD).'\'';
$res_conges = SQL::query($req_conges) ;
$num_row_conges = $res_conges->num_rows;
if($num_row_conges !=0)
    return $userAD;

return '';

}

a mon avis on peut faire plus propre au niveau du if mais je suis pas très a l'aise avec tout ça.

Matou25 commented 8 years ago

je cherche encore a ajouter un petit truc bien pratique, je suis toujours l'exemple de glpi. Dans certain cas il peut être nécessaire de se connecter avec un autre compte (admin ou un collègue qui veux poser un congé mais qui a déjà fermé son poste etc...) hors c'est impossible avec le sso. je vois 2 cas: 1- l'utilisateur ad n'existe pas dans libertempo -> fenêtre de login 2- l'utilisateur se déconnecte avec le bouton "power" et se retrouve sur la fenêtre de login, c'est ce que fait glpi il redirige a la déconnexion vers l'index avec un param ?noAUTO=1

je vais continuer mes recherche et test mais si tu as une idée je prends :-)

bonne journée

wouldsmina commented 8 years ago

la 2 me plait bien. c'est ce que j'ai fait ici : 60ebb47f95e94be4f02868144e0cebceb2e8e71a Est ce que tu pourrais partir de la version develop pour proposer tes modifications? sinon envoi moi les fichiers que tu as modifié, j'adapterai...

Shadok commented 8 years ago

Est-ce réalisable sans joindre le serveur au domaine ? Pour des serveurs en datacenter, je ne vois pas l'intérêt de les joindre à un domaine du LAN.

wouldsmina commented 8 years ago

seuls les postes sont joints au domaine, pas le serveur. Pour le paramétrage de kerberos dans apache tu le fais dans le virtualhost...

Matou25 commented 8 years ago

salut, je ne sais pas comment faire pour "partir de la version de dev" mais je veux bien essayer, il faut que je réinstalle la version de dev?

wouldsmina commented 8 years ago

installe ou mise à jour, mais surtout pas en prod. Si tu te sent pas de le faire, fait une bonne synthèse de tes modifs que je puisses le refaire...

wouldsmina commented 8 years ago

on le met pas dans la 1.8 (trop tard) mais on garde quand même!

Shadok commented 8 years ago

Je regarde pour faire un patch. Sur la branche develop, mais après que la branche 1.8 n'ait été créée non ?

prytoegrian commented 8 years ago

Oui, tu vas partir de develop pour chercher à rebrancher dessus. Tu peux le faire à n'importe quel moment vu que le process c'est : develop -> beta -> master -> branche de version

La seule contrainte donc, pour que ce que tu vas faire soit dans la 1.9, est que l'on doit merger ta PR sur SSO après que l'on aie fait le merge de develop dans beta, mais j'ai aucun doute là dessus.

Shadok commented 8 years ago

C'est chose faite, mais je n'ai pas moyen de tester le résultat.

Shadok commented 8 years ago

Il y a quand même quelque chose qui me dérange dans tout ça.

Car si on s'identifie par SSO, cela veut dire que les utilisateurs ont été importés via ldap et donc sont dans la base de données dbconges. Au final, cela revient juste à récupérer $_SERVER['REMOTE_USER'] et à en extraire l'username (en ignorant le domaine) dont on vérifiera l'existence dans dbconges.

Cela signifie que n'importe quel utilisateur d'un autre domaine mais avec le même identifiant pourra accéder à l'application, voire même un utilisateur envoyant les bonnes informations en entête, sans même faire partie d'un domaine.

C'est donc bien pour une application sur un serveur interne, mais pas si le site est accessible publiquement.

wouldsmina commented 8 years ago

vue que le poste doit être identifié dans l'AD, oui ce n'est qu'en interne. Pour le serveur, apache doit contrôler la session avec KrbServiceName HTTP. C'est expliqué dans le premier poste de @Matou25.

Cela signifie que n'importe quel utilisateur d'un autre domaine mais avec le même identifiant pourra accéder à l'application, voire même un utilisateur envoyant les bonnes informations en entête, sans même faire partie d'un domaine.

Je m'étais posé la même question, mais non, apache controle sur le serveur AD que tu as parametré...

Shadok commented 8 years ago

Bon, cela donnerait ceci : https://github.com/Shadok/Libertempo/commit/b229cb3f39e15df28aab6a14cb4544174b2231d4

Tu peux y jeter un œil avant que je fasse un push sur ta branche develop stp ?

Shadok commented 8 years ago

J'ai pris vos remarques en compte et modifié le code en conséquence. Le push est effectué.