[PHP] Get username/session windows (NT logon)

Fermé
AlexKidd - 5 mai 2009 à 09:58
 NumeroSix - 6 mars 2013 à 12:29
Bonjour,

Après près de 8 Heures de recherches sur la toile, plus de 800 pages web consultées, je vous demande votre aide à nouveau.

Je travaille sur un Intranet avec serveur Apache. Je récapitulerai tout en fin de message.

Je cherche à obtenir le nom d'utilisateur de la session Windows connecté. En gros le nom d'utilisateur que l'on entre pour ouvrir la session windows.
Le but étant de récupérer ce nom d'utilisateur windows pour faire des recherches dans l'Active Directory ou la base de données sans proposer de formulaire de login.
J'ai testé beaucoup de solutions, mais rien ne satisfait toutes mes conditions.

La solution doit :
- Fonctionner sur Internet Explorer (à partir de la version 6 - la 8 je m'en fous un peu)
- Fonctionner sur Firefox.
- Ne pas demander à l'utilisateur de saisir des informations.
- Pas d'ASP
- Pas d'ActiveX, JScript ou VBscript qui ne fonctionne que sur IE.
- Fonctionne tout le temps. (Pas un poste sur 3 par exemple)

Je vous dis ce que j'ai déjà testé :

* Utiliser le protocole NTLM :
Souci : Sur Firefox demande de saisir des informations. Sur IE, NTLM tue le POST (Mon précédent TOPIC où j'ai galéré à trouver la cause d'ailleur)

* Utiliser les variables de serveur :
$_SERVER['REMOTE_USER']
$_SERVER['PHP_AUTH_USER']
$_SERVER['AUTH_USER']
$_SERVER['LOGON_USER']

Mais elles sont toutes vide.
Même avec ceci (voir ci-dessous) dans un .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L]
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
</IfModule>

J'ai testé avec le module sspi_auth mais il en change rien. J'ai vérifié sur le phpinfo, il était bien "loadé" pourtant.
Également testé le mod ntlm mais il faut le compiler, j'ai rien compris et même pas sûr sur ça marchera.

* Utiliser ce bout de code :
$ip = getenv("REMOTE_ADDR");
$nbtstat = "nbtstat -a ".$ip;
$username = "";
exec ($nbtstat, $result);
foreach ($result as $row)
{
if (strpos($row, "<03>"))
{
$username = strtok($row, " ");
}
}

Souci : Très loin de fonctionner tout le temps.

Puis j'ai testé beaucoup d'autre chose mais qui me retournait le username du Serveur et nom de l'utilisateur.

Donc je vous demande si quelqu'un connait une solution.
Peut-être en executant une commande windows avec exec. Je ne sais pas trop.
Je pensais faire un echo %USERNAME% sur le poste du client, mais je ne sais pas si c'est possible.

Je dispose de :
Nom de la machine du client.
Son IP réseau.

Récapitulatif technique :
Serveur Apache : Windows NT APPACHE 5.0 build 2195
PHP : Version 5.2.3
OS des utilisateurs : Windows 2000 à XP

N'hésitez pas à demander plus d'informations si besoin et faire des propositions même farfelu tant qu'elle sont possible sans faille de sécurité énorme (mais dites toujours). J'ai vraiment besoin de ce username.

Je remercie déjà ceux qui ont eu le courage de tout lire et ceux qui proposeront des solutions.
Merci.
A voir également:

11 réponses

Bonjour,

Je viens faire part de mes dernières infos sur le sujet. J'avais laissé un peu de coté ce système quand j'ai vu que le mod_auth_sspi fonctionnait.
Je donne ces infos pour les personnes qui passeront par ici plus tard. Pour qu'il ne galère pas autant que moi.

Tout d'abord, le mod_auth_sspi a fini par me poser un problème. En effet, lorsque les utilisateurs de l'intranet passaient de l'intranet où il y avait l'authentification NTLM grâce au mod, à un autre script dans un autre dossier, je me suis retrouvé avec mon problème de POST.
Ce problème de POST ne se pose que sous Internet Explorer.
Les solutions que j'avais été alors :
- Déployer Firefox partout. Mais les utilisateurs ne sont pas prêt.
- Placer le dossier où les POST ne fonctionne pas dans le dossier du site Intranet. Mais ça implique qu'il faudra faire à chaque fois pareil à l'avenir et on se retrouvera avec un seul dossier. (Nécessaire seulement si on passe du site à un autre endroit en dehors)
- Ou bien appliquer le mod à tous les dossier. Mais c'est une solution un peu excessive je trouve. Et le jour où on ne veut pas le NTLM à un endroit précis c'est foutu.

J'ai donc opté pour une autre solution en discutant avec les membres du Service Informatique.
Cette solution consiste à créer un fichier contenant le username au moment de l'ouverture de la session windows. Le nom du fichier sera le nom de la machine. Et il sera écrasé à chaque fois qu'une nouvelle session Windows est ouverte.

Je vais vous coller mon script VBS (mixte de plusieurs bout de code piqué sur le net car je ne connais pas le VB). J'enlève une partie du code qui est propre au service à cause de certain serveur.
Voici ce code :
' Récupération du nom de la Machine sous TSE '
Dim WshShell
Dim ComputerName
Dim objNetwork
Set objNetwork = WScript.CreateObject("WScript.Network")

ComputerName = objNetwork.ComputerName

' Récupération du username '
Dim strUserName
strUserName = objNetwork.UserName 

' Initialisation des paramètres pour la création et l'écriture dans le fichier'
Dim oFSO, oFile
Dim f
Dim strDirectory, strFile
strDirectory = "\\serveur\ou_chemin\repertoire\"
strFile = ComputerName & ".txt"

' Création du fichier et écriture du username '
Set oFSO = CreateObject("Scripting.FileSystemObject")
If oFSO.FolderExists(strDirectory) Then
	Set oFile = oFSO.CreateTextFile(strDirectory & strFile, true)
	oFile.write(UCase(strUserName))
End if


Je peux ensuite avec une fonction PHP récupérer le contenu du fichier.
Pour cela j'utilise gethostbyaddr($_SERVER['REMOTE_ADDR']); qui me retourne nom_machine.nom_domaine.domaine
Exemple : pc_1.mondomaine.com
Voici cette fonction - il faudra l'adapter à votre situation si vous l'utilisez :
/**
 * Retourne le Username de la session windows ouverte d'un utilisateur.
 * @return NULL si le username n'a pas pu être récupéré.
 *              Ou le Username de la session windows ouverte d'un utilisateur.
 */
function getRemoteUser()
{
	$host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
	$ComputerName = explode('.', $host);
	
	// Chemin du fichier dans lequel il faut lire.
	$path_file = 'http://domaine_serveur/repertoire_ou_sont_cree_les_fichier/'.$ComputerName[0].'.txt';

	// Valeur par défaut si le username ne peut pas être lu.
	$REMOTE_USER = NULL;
	// Valeur par défaut de retour de la fonction fopen.
	$rsc_file = FALSE;
	// Si fopen ne fonctionne pas, $rsc_file contiendra la valeur par défaut. Sinon $rsc_file contiendra TRUE.
	$rsc_file = @fopen($path_file, 'r');

	//Si $rsc_file ne vaut pas FALSE on peut continuer.
	if($rsc_file)
	{
		$REMOTE_USER = '';
		//Tant que l'on est pas à la fin du fichier.
		while(!feof($rsc_file))
		{
			//Récupère la ligne en cours et l'ajoute au contenu de la variable $REMOTE_USER
			$REMOTE_USER .= fgets($rsc_file); 
		}

		// Fermeture du fichier.
		fclose($rsc_file);
	}
	
	// On retourne le résultat.
	return $REMOTE_USER;
}


Et voilà. Avec cela j'arrive à me démerder. Et j'ai pas de NTLM qui me bousille mes POST.

Je voudrais aussi revenir sur la pref de firefox. J'ai également un logon script pour le fichier user.js
Au départ il contenait la ligne pour l'authentification automatique. Mais maintenant elle est inutile mais contient des lignes pour réactivé le protocole file.
Pour ceux que ça interesse, voila le contenu de user.js :
// Politique de sécurité.
user_pref("capability.policy.policynames", "localfilelinks");
user_pref("capability.policy.localfilelinks.sites", "http://votreDomaine");
user_pref("capability.policy.localfilelinks.checkloaduri.enabled", "allAccess");


Et voici el logon script qui copie le fichier seulement si il n'existe pas :
Dim stRep 'Nom du répertoire à parcourir
Dim oFSO,oFld, oPrN
Set oFSO = CreateObject("Scripting.FileSystemObject")
dim WshShell
Set WshShell = CreateObject("WScript.Shell")
stRep = WshShell.ExpandEnvironmentStrings("%APPDATA%") & "\Mozilla\Firefox\Profiles"
If oFSO.FolderExists(stRep) Then
Set oFld = oFSO.GetFolder(stRep).SubFolders
  For each oFld in  oFSO.GetFolder(stRep).SubFolders
  If oFSO.FileExists(stRep & "\" & oFld.Name & "\user.js") Then
  Else
   oFSO.CopyFile "\\appache\intranet\intranet\Ressources\user.js", stRep & "\" & oFld.Name & "\user.js", True
  End If
 Next
End If


Désolé pour tous ce blabla, mais je ne veux pas que d'autre galère comme moi.
Bon voilà en espérant que j'en aiderai certain et si ce n'est pas fait, je vous invite à lire les réponses de Panoramix qui m'ont permise d'arriver là. ça aura été compliqué mais là ça marche.
Moi je te remercie encore Panoramix,

Ciao tous le monde.
10
J'ai galéré pendant très longtemps sur ce problème de POST je vous donne donc ma solution :
J'ai mis le header suivant en haut de mon fichier ntlm.php :
header('WWW-Authenticate: Negociate');

Depuis plus de problème de POST :)

Je me confronte toutefois à une autre merde... mon service passe sous Windows Seven et malheureusement c'est le protocole ntlm v2 qui est utilisé... La connexion est donc systématiquement refusée !
Quelqu'un aurait-il une idée ?
0
Sous windows 7, dans les stratégies locales du client Windows, aller dans : Config Ordi > Windows > Sécurité > Stratégies locales > sécurité et modifier l'option Sécurité Réseau :niveau authentification LAN Manager. Mettre Envoyer LM et NTLM - utiliser NTLM2 si négocié.
Une GPO fera l'affaire sur un réseau d'entreprise.
0
Enfin, il reste un petit détail à corriger, ceux qui vont télécharger FireFox (avant le déploiement) n'auront pas cette pref avec la valeur par défaut que je souhaite. Il faut trouver un moyen pour que de nouveau utilisateurs de FF ne soit pas dérangé avec cette fenêtre d'authentification. Ils ont déjà fait un beau geste en passant d'IE à FF alors il ne faut pas les faire revenir sur leur décision.

Je crois que l'user.js n'existe pas par défaut (à vérifier) ce qui permettrait de l'utiliser et de faire le paramétrage via un logonscript.

Panoramix, si vous repassez par là, pouvez vous me confirmer que je suis arrivé, avec votre aide bien sur qui m'aura été d'un énorme secours, à la solution optimal (si on oublie Kerberos) ?

Le principal est de proposer une solution qui fonctionne, et, vous ne semblez pas trainé!


Encore merci.

Pas de quoi
1
Merci Panoramix.

Je regarde ces solutions dès que possible qui m'ont pas l'air évidente à installer.
Je vous tiens au courant.
0
Pour le dernier lien que tu as mis, c'est ce que j'ai utilisé, mais ça me bloquait mes POST. Toutes mes variables POST étaient vide. Cela a d'ailleur était le sujet d'une autre question que j'ai posé ici mais je ne savais pas que c'était ntlm qui me les bloquaient.
Et sur FireFox j'avais une fenêtre me demandant de saisir des identifiants. ça doit être la config à modifier dont tu parlais tout à l'heure pour éviter de l'avoir.

Et avec le mod auth_sspi (mod_ntlm pour Apache 2.x), il semble qu'il y est le même problème :

https://forum.hardware.fr/hfr/systemereseauxpro/Reseaux/apache-sspi-post-sujet_849_1.htm

Je vais quand même tester.
Sinon je me rabattrais sur Kerberos. Sauf que j'ai vite fait regardé, j'ai failli vomir...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Impossible de faire fonctionner le module pour apache mod_auth_sspi. Apache refuse de redémarrer.

Et Kerberos j'y comprend rien de rien. Vous n'auriez pas un tutoriel clair sur la façon d'utiliser l'authentification Kerberos avec apache ?
Je désespère, ça fera trois jour que j'essaye d'avoir une authentification transparente pour les utilisateurs...

Sinon merci quand même de m'avoir mis sur la piste.
0
J'ai réussi à faire fonctionner le module mod_auth_sspi.
En faite j'ai utilisé Apache 2.0.59 au lieu d'une 2.2.x

Sauf que ce module fait la moitier de ce que je veux. Je m'explique.
Que ce soit sous IE ou sous FireFox, il me prompt. Et si je met n'importe quoi, il me met Invité dans la variable REMOTE_USER. Donc dommage...

En faisant la modification dont vous parliez Panoramix sur FireFox, la récupération du username windows fonctionne bien. Mais comme ça ne marche pas sans la modif, (chose que les utilisateurs ne feront pas), je ne peux pas utiliser ce mod. Il aurai au moins fallu que sous IE (Navigateur majoritaire ici) l'authentification soit transparente.

Je continuerai à fouiller un peu le web on ne sait jamais. Et kerberos je suis largué complet pour une utilisation sur windows.

Si vous aviez plus de précision, correction ou autre solution, je suis prenneur.

Merci
AK.
0
Bonjour,

Je vous fais part de mon avancement.
J'avais testé le mod_auth_sspi sur mon PC personnel. Et donc ça ne marchait pas comme l'indique mon précédent post.
J'ai quand même voulu le tester en condition réel sur le site intranet de l'entreprise, et ça marche impeccable avec Internet Explorer 6 et 7 (il faudra que je fasse plus de tests avec les postes du personnel - mais en attendant je vais considérer que ça fonctionne).

Par contre FireFox prompt.

En effet un Active Directory est utilisé - Avez vous une idée de ce côté ?

Il faut gérer l'ensemble des postes dont dispose les employés de l'hôpital.
Pas vraiment d'outil de déploiement, mais par Scripting, on me dit que l'on peut modifier un fichier sur tous les postes. Je vais donc creuser votre idée de user.js et je repars sur Google.......

En ce qui concerne Kerberos, je suis en Stage, je vais perdre trop de temps si j'essaie de comprendre comment implémenter ce truc. Je le met de coté, mais je garde ne mémoire cette outil peut-être qu'il me servira un jour.

Merci encore une fois d'avoir répondu.
Je vous tiens au courant pour le user.js

Ciao,
AK
0
Bien la technique du user.js marche bien, sauf que j'ai un peu changé la manière de procéder.

Je résume pour ceux qui passeront pas là qui souhaiteraient savoir comment faire. Il s'agit de la méthode décrite par Panoramix plus haut :

1./ Donc j'ai crée un fichier nommé user.js et contenant :
// Authentification NTLM automatique.
user_pref("network.automatic-ntlm-auth.trusted-uris", "http://mondomaine");

Modifier bien entendu mondomaine par votre domaine.

2./ Puis il faut placer ce fichier dans le répertoire profiles de Mozilla correspondant à l'utilisateur.
Pour savoir où il se trouve vous pouvez regarder ici : https://www.hugedomains.com/domain_profile.cfm?d=geckozone&e=org
Ce fichier dois se retrouver normalement au même endroit qu'un fichier prefs.js

3./ Lancez ou redémarrer FireFox.

Pour vérifier si cela à marché, vous pouvez taper about:config dans la barre d'adresse et regarder à network.automatic-ntlm-auth.trusted-uris si la valeur est celle entré dans le fichier user.js


Comme je le disais, cette solution marche très bien. Mais sauf erreur de ma part, elle est lié à un utilisateur. Si un autre utilisateur vient sur le PC, la config ne sera pas modifié.

J'ai donc procédé autrement.
J'ai modifié le fichier : C:\Program Files\Mozilla Firefox\defaults\pref\firefox.js en y ajoutant à la fin :

// Authentification NTLM automatique.
pref("network.automatic-ntlm-auth.trusted-uris", "http://mondomaine");

Attention: Ce n'est plus user_pref mais pref. Attention si vous croyez qu'il s'agit de la même ligne qu'au dessus !

Je n'ai pas encore testé, mais je pense qu'avec la modification de ce fichier, la config sera appliquée à tous les utilisateurs du PC.

Le jour où FireFox sera déployé sur l'ensemble des PC, il faudra le déployer avec la pref directement ajouté.

Enfin, il reste un petit détail à corriger, ceux qui vont télécharger FireFox (avant le déploiement) n'auront pas cette pref avec la valeur par défaut que je souhaite. Il faut trouver un moyen pour que de nouveau utilisateurs de FF ne soit pas dérangé avec cette fenêtre d'authentification. Ils ont déjà fait un beau geste en passant d'IE à FF alors il ne faut pas les faire revenir sur leur décision.
Cela reste un peu du bricolage (finalement est-ce que ce n'est pas ça le web ?!) mais au moins ça à le mérite de marcher au moins sur IE et ça devrait marcher sur les postes qui ont déjà FireFox d'installer.

Panoramix, si vous repassez par là, pouvez vous me confirmer que je suis arrivé, avec votre aide bien sur qui m'aura été d'un énorme secours, à la solution optimal (si on oublie Kerberos) ?
J'avais également l'impression que vous aviez une idée avec l'AD ?

Encore merci.
AK
0
Bonjour,

Pour réaliser ce que tu veux, c'est à dire récupérer le login (lorsque la session est ouverte sur un réseau), tu peux utiliser kerberos qui fonctionne sur IE et FF, les seuls à ma connaissance. Pour FF tu devra amender une pref:
network.negotiate-auth.trusted-uris que tu peux initialiser pour les tests avec http://,https://. Ce n'est peut être le plu aisé à mettre en oeuvre mais cela fonctionne parfaitement.

Pour NTLM nous avons utilisé un module mod_auth_ntlm_winbind (sur linux) mais je crois qu'il y a un équivalent sur Windows et cela fonctionne en http. Les navigateurs Internet explorer;, Firefox, Opera, Safari (Windows) supporte ce mode d'authentification. Ce qui pose problème c'est ntlm sous https avec IE.

De même sur FF pour utiliser NTLM et ne pas être prompté tu devras amender une pref:
network.automatic-ntlm-auth.trusted-uris où tu peux utiliser les mêmes valeurs pour les tests sinon ce sera un nom de domaine à fournir ex: http://mondomaine

voilà

Cdt
-1
Kerberos est le choix à faire si l'on dispose d'un annuaire ex: Active Directory. Cela suppose la création de jeton.

Rectification concernant IE, il fonctionne aussi avec NTLM sous https. Cela nécéssite la création d'un certificat.

Une troisième solution plus restrictive mais facile en php.


https://codes-sources.commentcamarche.net/
-1
En faisant la modification dont vous parliez Panoramix sur FireFox, la récupération du username windows fonctionne bien. Mais comme ça ne marche pas sans la modif, (chose que les utilisateurs ne feront pas), je ne peux pas utiliser ce mod. Il aurai au moins fallu que sous IE (Navigateur majoritaire ici) l'authentification soit transparente.

Avec un script et un outil de déploiement (ex: SMS) vous pourriez amendé les prefs en utilisant le fichier user.js. En effet ce fichier modifie au démarrage de firefox le prefs.js . De même sous IE vous pourriez ajouter le domaine comme site intranet local. L'utilisateur n'aurait donc rien à faire.
Combien de postes devez vous prendre en compte? Utilisez vous Active Directory? Avez vous un outil de déploiement (ex: SMS de Microsoft)?
Kerberos requiert pour sa mise en oeuvre un peu de temps, et, ce n'est 3 jours qui vous suffiront pour l'appréhender. Vous pourriez trouvé de l'information les sites de Microsoft du MIT:

www.microsoft.com
http://web.mit.edu/Kerberos/

Je n'ai pas de tutoriel mais regardez sur google kerberos 5. Il est probable que vous trouverez des tutorials et des livres (ex: Librairie Eyrolles sur Paris).

Cdt

-1