Comment interagir par programme avec winlogon?
Je souhaite utiliser un service Windows pour déverrouiller le poste de travail par programmation, à l'aide du nom d'utilisateur et du mot de passe du compte.
Cet article https://technet.Microsoft.com/en-us/library/dn751047(v=ws.11).aspx explique le flux de travail d'authentification d'ouverture de session sous Windows dans l'image suivante:
Comme indiqué ci-dessus, à l'étape 5, l'utilisateur entre les informations d'identification dans l'interface utilisateur de connexion. Ce que je veux réaliser, c'est que le service Windows entre les informations d'identification et que winlogon établisse la connexion.
Il n'y a pas d'API Winlogon pour atteindre cet objectif. Comme indiqué dans d'autres questions, l'utilisation de la fonction LogonUser
de winapi réussit l'authentification et renvoie un jeton, mais ne bascule pas sur le bureau de l'application et l'interface utilisateur de connexion reste à l'écran.
La plupart des articles et des réponses SO suggèrent des fournisseurs d'informations d'identification, mais tous les exemples de fournisseurs d'informations d'identification requièrent une interaction de l'utilisateur avec l'interface utilisateur Logon.
Mise à jour: Je vois que certains utilisateurs n'ont pas bien compris la question et proposent des solutions de contournement qui ne sont pas utiles pour mon cas. Le flux de travail que j'essaie de réaliser est le suivant:
- Le service Windows démarre au démarrage de Windows (terminé).
- Le même service Windows dispose d'un service Web et accepte les demandes HTTP via une API (terminé).
- L'utilisateur fournit des informations d'identification au service via l'API à partir d'un autre périphérique (terminé).
- Les informations d'identification fournies sont utilisées pour se connecter au poste de travail.
4.1 Les identifiants fournis permettent également de déverrouiller le poste de travail en cas de verrouillage (WinKey + L). - (Facultatif) Le service expose les comptes Windows via l'API.
- (Facultatif) L'utilisateur peut spécifier au service quel compte il veut utiliser pour se connecter.
Pour l'instant, je suis intéressé par les étapes 4 et 4.1.
Juste en passant ... Mais parmi les exemples de Microsoft, n'y a-t-il pas un fournisseur d'informations d'identification qui utilise une entrée asynchrone? J'en ai certainement écrit un qui se connecte à un utilisateur qui numérise une empreinte digitale acceptable, quelle que soit la mosaïque affichée. Pour moi, cela signifie que l'interaction avec LogonUI ne doit être qu'implicite, mais il me manque peut-être quelque chose.
Mais peut-être que je ne suis pas. Bien que je ne doute pas que l'intention est que l'entrée asynchrone provienne d'un utilisateur agissant sur du matériel, comme pour le balayage d'un doigt, je ne m'en souviens pas en règle générale. Si ce n'est pas le cas, votre option de programmation peut présenter les informations d'identification comme si elles avaient été collectées de manière asynchrone - pas à partir d'un périphérique évidemment connecté à l'ordinateur mais à partir de votre canal latéral HTTP avec qui sait quoi.
Alors, pouvez-vous demander à un fournisseur d'informations d'identification d'écouter RPC de votre service pour recevoir une notification des informations d'identification que votre service a collectées via son canal latéral? Ou demandez à votre service d'écouter RPC auprès de votre fournisseur d'informations d'identification pour lui demander quelles informations d'identification sont encore disponibles. Je ne serais peut-être pas surpris si une direction était fermée - pour des raisons de sécurité, même - mais j'aurais pensé que l'une ou l'autre pouvait fonctionner.
Que vous souhaitiez faire cela ou non, je ne veux pas en parler.
Non pas que je pardonne cela, mais simplement en vous donnant une solution au problème. Et il n'interagit pas par programme avec le processus WinLogon. Il travaille par programme autour de cela.
Utilisez la propriété de connexion automatique de Windows. Et redémarrez pour passer à cet utilisateur . Notez que cela implique de stocker le mot de passe dans le registre, en texte clair.
Définir spécifiquement ces regkeys
HKLM\LOGICIEL\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogin HKLM\LOGICIEL\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName HKLM\LOGICIEL\Microsoft\Windows NT\CurrentVersion\Winlogon\Winlogon\DefaultPassword
* Modifier *
Aide avec 4. N'aide pas avec 4.1. Sauf si vous voulez redémarrer pour déverrouiller ce dont je doute.
Une autre solution qui semble prometteuse et mérite d’être explorée est évoquée dans une question plus ancienne https://stackoverflow.com/a/35173886/4640588
J'ai écrit une solution commercial pour cela, appelée SasLibEx. SasLibEx est une bibliothèque, destinée aux développeurs, supportant c/c ++ et Delphi de manière native.
SasLibEx peut:
- Simuler Ctrl Alt Suppr (séquence d'attention sécurisée)
- Annuler Ctrl Alt Suppr
- Verrouiller le poste de travail
- Déverrouiller la station de travail (sans informations d'identification)
- Désactiver Ctrl Alt Suppr
- Activer Ctrl Alt Suppr à nouveau
- Annuler la demande en attente de l'UAC
- Le bureau est-il verrouillé?
Votre tâche consiste à implémenter des interfaces de fournisseur d’identifiants et au point où votre service reçoit des identifiants qui peuvent facilement être transférés à LogonUI - regardez ceci answer .
L'objectif est d'implémenter une mosaïque par défaut qui peut contenir ces informations d'identification.
Mon propre fournisseur d'informations d'identification a également un comportement d'ouverture de session/déverrouillage automatique dans certains cas d'utilisation.
J'avais presque les mêmes exigences pour un framework basé sur Selenium que je construis. En résumé, je devais exécuter une application dans la station Windows d'un utilisateur (WinSTA0), ce qui signifiait que un utilisateur devait être connecté à une machine virtuelle.
J'ai déjà créé un projet avec un gestionnaire d'informations d'identification et je l'ai utilisé pour réaliser le workflow suivant:
- Démarrer une machine virtuelle, copier des composants avec Powershell
- Installez CredManager, redémarrez la machine virtuelle
- Cred Manager crée un utilisateur aléatoire, l'enregistre dans une base de données
- Se connecter avec cet utilisateur
- L'utilisateur a démarré automatiquement dans le registre d'une application et celle-ci démarre un serveur Web pouvant être contacté pour lancer des sessions Selenium.
Si je comprends bien vos besoins, vous devrez créer un gestionnaire d'informations d'identification qui exposera un serveur (http, tubes nommés, etc.) à contacter avec les informations d'identification pour la connexion automatique - inutile de passer du temps sur l'interface utilisateur ici. Utilisez la méthode Advice
dans votre implémentation ITestWindowsCredentialProvider
pour démarrer votre serveur et la UnAdvice
pour l’arrêter.
Je suggérerais ce qui suit pour vous aider à y arriver:
- Utilisez un service de journalisation externe (comme app-insights) pour obtenirle feed-back de votre service et faciliter le débogage
- Utilisez un VM comme bonne pratique, car une défaillance critique de Winlogon rendra l'ordinateur inutilisable.
- Utilisez try catch au niveau supérieur de toutes vos méthodes d'implémentation de composant COM pour avaler une exception et sauvegarder les plantages de winlogon.
En outre, pour une vue d'ensemble, vous devrez garder à l'esprit que tous ces processus ont un accès (et une durée de vie des composants COM) différent aux stations Windows, aux ordinateurs de bureau et fonctionnent en tant qu'utilisateurs différents. Je ne pense cependant pas que cela vous concerne beaucoup.
Vous pouvez trouver le code du gestionnaire des identifiants de base ici: https://github.com/phaetto/windows-credentials-provider