Question

J'utilise le win32 api LogonUser:

token = LogonUser(...)
WindowsIdentity newId = new WindowsIdentity(token);            
WindowsImpersonationContext impersonatedUser = newId.Impersonate();

Cependant lors de l'appel d'un service WCF après cela, je ne suis pas en mesure d'utiliser l'identité personnifié. Je pense que c'est parce que impersonatedUser.ImpersonationLevel est égal à Impersonation.

Est-ce la raison? Un niveau de ImpersonationLevel.Identification ce que je dois? Comment obtenir un tel niveau?

Était-ce utile?

La solution

Je ne sais pas si cela fonctionnera pour WCF. Mais nous l'utilisons dans notre application web de production pour l'usurpation d'identité pour lire et écrire des fichiers sur le système de fichiers. Vous devrez définir les années API pour AdvApi32.LogonUser, AdvApi32.DuplicateToken et Kernel32.CloseHandle et assurez-vous de fermer le WindowsImpersonationContext lorsque vous avez terminé.

    /// <summary>impersonates a user</summary>
    /// <param name="username">domain\name of the user account</param>
    /// <param name="password">the user's password</param>
    /// <returns>the new WindowsImpersonationContext</returns>
    public static WindowsImpersonationContext ImpersonateUser(String username, String password)
    {
        WindowsIdentity winId = WindowsIdentity.GetCurrent();
        if (winId != null)
        {
            if (string.Compare(winId.Name, username, true) == 0)
            {
                return null;
            }
        }

        //define the handles
        IntPtr existingTokenHandle = IntPtr.Zero;
        IntPtr duplicateTokenHandle = IntPtr.Zero;

        String domain;
        if (username.IndexOf("\\") > 0)
        {
            //split domain and name
            String[] splitUserName = username.Split('\\');
            domain = splitUserName[0];
            username = splitUserName[1];
        }
        else
        {
            domain = String.Empty;
        }

        try
        {
            //get a security token

            bool isOkay = AdvApi32.LogonUser(username, domain, password,
                (int) AdvApi32.LogonTypes.LOGON32_LOGON_INTERACTIVE,
                (int) AdvApi32.LogonTypes.LOGON32_PROVIDER_DEFAULT,
                ref existingTokenHandle);

            if (!isOkay)
            {
                int lastWin32Error = Marshal.GetLastWin32Error();
                int lastError = Kernel32.GetLastError();

                throw new Exception("LogonUser Failed: " + lastWin32Error + " - " + lastError);
            }

            // copy the token

            isOkay = AdvApi32.DuplicateToken(existingTokenHandle,
                (int) AdvApi32.SecurityImpersonationLevel.SecurityImpersonation,
                ref duplicateTokenHandle);

            if (!isOkay)
            {
                int lastWin32Error = Marshal.GetLastWin32Error();
                int lastError = Kernel32.GetLastError();
                Kernel32.CloseHandle(existingTokenHandle);
                throw new Exception("DuplicateToken Failed: " + lastWin32Error + " - " + lastError);
            }
            // create an identity from the token

            WindowsIdentity newId = new WindowsIdentity(duplicateTokenHandle);
            WindowsImpersonationContext impersonatedUser = newId.Impersonate();

            return impersonatedUser;
        }
        finally
        {
            //free all handles
            if (existingTokenHandle != IntPtr.Zero)
            {
                Kernel32.CloseHandle(existingTokenHandle);
            }
            if (duplicateTokenHandle != IntPtr.Zero)
            {
                Kernel32.CloseHandle(duplicateTokenHandle);
            }
        }
    }

Autres conseils

  

après cela, je ne suis pas en mesure d'utiliser la   identité personnifié

L'usurpation d'identité devrait être efficace pour l'accès sur la même case, mais pas sur le réseau.

Il peut être, comme le montre le code de consultutah, que vous avez juste besoin d'appeler DuplicateToken () afin de convertir le jeton de connexion à un jeton d'emprunt d'identité avant de pouvoir être utilisé.

  

Je pense que c'est parce que impersonatedUser.ImpersonationLevel est égal à Impersonation.

Si vous devez agir en tant que l'utilisateur personnifié à d'autres systèmes, vous avez besoin d'un niveau plus élevé d'usurpation d'identité appelée « délégation ». Ceci est essentiellement équivalent à vous comme les ayant le mot de passe de l'utilisateur afin que vous puissiez représenter à d'autres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top