Pregunta

Estoy usando la API LogonUser Win32:

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

Sin embargo cuando se llama a un servicio WCF después de esto yo no soy capaz de utilizar la identidad suplantada. Creo que esto se debe a que es igual impersonatedUser.ImpersonationLevel suplantación.

Es esta la razón? Es un nivel de ImpersonationLevel.Identification lo que necesito? Como llegar a tal nivel?

¿Fue útil?

Solución

No sé si esto funcionará para WCF. Pero lo usamos en nuestra aplicación Web de producción para la suplantación de leer y escribir archivos en el sistema de archivos. Tendrá que definir las API para AdvApi32.LogonUser, AdvApi32.DuplicateToken y Kernel32.CloseHandle y asegúrese de cerrar la WindowsImpersonationContext cuando haya terminado.

    /// <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);
            }
        }
    }

Otros consejos

  

Después de esto yo no soy capaz de utilizar el   identidad suplantada

La suplantación debe ser eficaz para el acceso en la misma caja, pero no en la red.

Puede ser, como se muestra en el código de consultutah, que sólo tiene que llamar DuplicateToken () con el fin de convertir el símbolo de conexión a un testigo de suplantación antes de que pueda ser utilizado.

  

Creo que esto se debe a que es igual impersonatedUser.ImpersonationLevel suplantación.

Si tiene que actuar como el usuario suplantado a otros sistemas, es necesario un mayor nivel de suplantación denominado 'delegación'. Esto es básicamente equivalente a tener la contraseña del usuario para que pueda representarse a sí mismo como a otros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top