Authentifier un utilisateur avec carte à puce et login/mot de passe

Context

Lorsqu’un utilisateur ouvre une session Active Directory avec sa carte à puce, il arrive que certaines applications ne prennent pas en charge l’ouverture de session par carte à puce, mais nécessitent une connexion utilisateur/mot de passe classique.

Dilème

Lorsque vous utilisez la console MMC Utilisateurs et ordinateurs Active Directory, vous disposez uniquement de l’option « Une carte à puce est requise pour l’ouverture de session interactive » :


Cette action effectue les opérations suivantes :

  • Désactiver l’ouverture de session avec mot de passe
  • Modifier le mot de passe de l’utilisateur
  • L’utilisateur n’a pas de date d’expiration du mot de passe

Solution

Changement du compte utilisateur

Ne pas utiliser la console MMC utilisateurs et ordinateurs AD

Changer les propriétés en PowerShell

$oUser = [ADSI]("LDAP://" + $Props.distinguishedname)
Write-Output "Found user: $($oUser.DistinguishedName)"

Write-Output "   --> Setting SMARTCARD_REQUIRED (No password change)"
[int]$userFlags = $oUser.useraccountcontrol[0]
$oUser.useraccountcontrol = $userFlags -bor $ADS_UF_SMARTCARD_REQUIRED
$oUser.setinfo()

#    $oUser.ObjectSecurity
$self = [System.Security.Principal.SecurityIdentifier]'S-1-5-10'
[guid]$nullGuid = [guid]"00000000-0000-0000-0000-000000000000"

Write-Output "   --> Changing rights and attributes"
$oUser.get_ObjectSecurity().AddAccessRule($(New-Object DirectoryServices.ActiveDirectoryAccessRule `
    $self, "ExtendedRight", "Allow", $(GetADRightGuid("Reset Password"))  `
 ))

$oUser.get_ObjectSecurity().AddAccessRule($(New-Object DirectoryServices.ActiveDirectoryAccessRule `
 $self, "ExtendedRight", "Allow", $(GetADRightGuid("Change Password"))  `
 ))

$oUser.CommitChanges()

Vérifier si le mot de passe expire à l’ouverture de session

Sur l’unité d’organisation dans laquelle se trouve le compte, liez un objet de stratégie de groupe à un script de connexion PowerShell et ajoutez le script équivalent :

  $oUser = SearchAD -ADSearchBase $RootDSE.defaultNamingContext `
        -ADFilter "(&(objectClass=user)(objectcategory=person)(sAMAccountName=$($env:username)))" `
        -ADProperties "distinguishedname", "displayname", "samAccountName", "useraccountcontrol", "objectGUID", "PwdLastSet"
   
  $PwdLastSet = ([DateTime]::FromFileTime([Int64]::Parse($oUser.Properties["pwdlastset"])))
  $UF = [int32]$oUser.Properties["useraccountcontrol"][0]
  $bSmartCard = ($UF -bor 0x40000) -eq $UF
  $bExpiresPassword = ($UF -bor 0x10000) -eq $UF
   
  $pwdAge = (get-date) - $pwdLastSet
  $OutBox.AppendText("   --> DistinguishedName           : $($oUser.Properties["distinguishedname"])`n")
  $OutBox.AppendText("   --> DisplayName                 : $($oUser.Properties["displayname"])`n")
  $OutBox.AppendText("   --> Password expires            : $($bExpiresPassword)`n")
  $OutBox.AppendText("   --> Requires SmartCard          : $($bSmartCard)`n")
  $OutBox.AppendText("   --> Password date        (UTC)  : $($pwdLastSet)`n")
  $OutBox.AppendText("   --> Password age                : $($pwdAge.Days) Days $($pwdAge.Hours) Hours $($pwdAge.Minutes) Mn

if ($pwdAge.Days -lt 30) 
{
try {
   $oAdsUser = [adsi]$oUser.Path
   $oAdsUser.SetPassword($txtPassword1.Text)
   $oAdsUser.SetInfo()
   $OutBox.AppendText("Mot de passe changé avec succès`n")
}
catch {
				      [System.Windows.Forms.MessageBox]::Show($($Error[0].Exception.InnerException.Message), "Error happened",    [System.Windows.Forms.MessageBoxButtons]::OK)
   return $false
}

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.