Evaluar y enviar comentarios
MSDN
MSDN Library
 SecureStringToGlobalAllocUnicode (M...
Contraer todo/Expandir todo Contraer todo
Esta página es específica de
Microsoft Visual Studio 2005/.NET Framework 2.0

Hay además otras versiones disponibles para:
Biblioteca de clases de .NET Framework
Marshal.SecureStringToGlobalAllocUnicode (Método)

Nota: este método es nuevo en la versión 2.0 de .NET Framework.

Copia el contenido de un objeto SecureString administrado en la memoria no administrada.

Espacio de nombres: System.Runtime.InteropServices
Ensamblado: mscorlib (en mscorlib.dll)

Visual Basic (Declaración)
Public Shared Function SecureStringToGlobalAllocUnicode ( _
    s As SecureString _
) As IntPtr
Visual Basic (Uso)
Dim s As SecureString
Dim returnValue As IntPtr

returnValue = Marshal.SecureStringToGlobalAllocUnicode(s)
C#
public static IntPtr SecureStringToGlobalAllocUnicode (
    SecureString s
)
C++
public:
static IntPtr SecureStringToGlobalAllocUnicode (
    SecureString^ s
)
J#
public static IntPtr SecureStringToGlobalAllocUnicode (
    SecureString s
)
JScript
public static function SecureStringToGlobalAllocUnicode (
    s : SecureString
) : IntPtr

Parámetros

s

Objeto SecureString administrado que se va a copiar.

Valor devuelto

Dirección de la memoria no administrada donde se ha copiado el parámetro s o 0 si se ha proporcionado un objeto SecureString nulo.
Tipo de excepciónCondición

ArgumentNullException

El parámetro s es referencia de objeto null (Nothing en Visual Basic).

NotSupportedException

El equipo actual no ejecuta Microsoft Windows 2000 Service Pack 3 o posterior.

OutOfMemoryException

No hay memoria suficiente.

El método SecureStringToGlobalAllocUnicode resulta útil para el cálculo de referencias personalizado o para utilizarlo al combinar código administrado y no administrado. Dado que este método asigna la memoria no administrada necesaria para una cadena, libere siempre la memoria mediante una llamada al método ZeroFreeGlobalAllocUnicode.

NotaNota

Este método utiliza SecurityAction.LinkDemand para evitar que se le llame desde código que no sea de confianza; sólo el llamador inmediato debe disponer del permiso SecurityPermissionAttribute.UnmanagedCode. Si se puede llamar al código desde código de confianza parcial, no pase ninguna entrada de usuario a los métodos de la clase Marshal sin validación. Para conocer las limitaciones importantes que existen a la hora de utilizar el miembro LinkDemand, vea Demand frente a LinkDemand.

Notas para los llamadores Este método sólo se admite en equipos que ejecutan Microsoft Windows 2000 Service Pack 3 o posterior.

En el siguiente ejemplo de código se muestra cómo utilizar el método SecureStringToGlobalAllocUnicode con el que la función LogonUser no administrada va a realizar la suplantación con la clase SecureString. En el ejemplo se utiliza a continuación el método ZeroFreeGlobalAllocUnicode para hacer que el resultado sea cero y liberar la referencia de la cadena no administrada.

Visual Basic
Imports System
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Imports System.Security
Imports System.Security.Principal
Imports System.Text




Module ImpersonationExample


    ' PInvoke into the Win32 API to provide access to the 
    ' LogonUser and CloseHandle functions.
    <DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> Function LogonUser(ByVal username As String, ByVal domain As String, ByVal password As IntPtr, ByVal logonType As Integer, ByVal logonProvider As Integer, ByRef token As IntPtr) As Boolean

    End Function


    <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> Function CloseHandle(ByVal handle As IntPtr) As Boolean

    End Function

    ' Define the required LogonUser enumerations.
    Const LOGON32_PROVIDER_DEFAULT As Integer = 0
    Const LOGON32_LOGON_INTERACTIVE As Integer = 2



    Sub Main(ByVal args() As String)
        Try
            ' Display the current user before impersonation.
            Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name)

            ' Ask the user for a network domain.
            Console.Write("Please enter your domain:")

            Dim domain As String = Console.ReadLine()

            ' Ask the user for a user name.
            Console.Write("Please enter your user name:")

            Dim username As String = Console.ReadLine()

            ' Ask the user for a password.
            Console.Write("Please enter your password:")

            Dim passWord As SecureString = GetPassword()

            ' Impersonate the account provided by the user.
            Dim userContext As WindowsImpersonationContext = ImpersonateUser(passWord, username, domain)

            ' Display the current user after impersonation.
            Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name)
        Catch e As Exception
            Console.WriteLine(e.Message)
        End Try

        Console.ReadLine()

    End Sub



    Function GetPassword() As SecureString
        Dim password As New SecureString()

        ' get the first character of the password
        Dim nextKey As ConsoleKeyInfo = Console.ReadKey(True)

        While nextKey.Key <> ConsoleKey.Enter
            If nextKey.Key = ConsoleKey.BackSpace Then
                If password.Length > 0 Then
                    password.RemoveAt(password.Length - 1)

                    ' erase the last * as well
                    Console.Write(nextKey.KeyChar)
                    Console.Write(" ")
                    Console.Write(nextKey.KeyChar)
                End If
            Else
                password.AppendChar(nextKey.KeyChar)
                Console.Write("*")
            End If

            nextKey = Console.ReadKey(True)
        End While

        Console.WriteLine()

        ' lock the password down
        password.MakeReadOnly()
        Return password

    End Function



    Function ImpersonateUser(ByVal password As SecureString, ByVal userName As String, ByVal domainName As String) As WindowsImpersonationContext
        Dim tokenHandle As IntPtr = IntPtr.Zero

        Dim passwordPtr As IntPtr = IntPtr.Zero

        Dim returnValue As Boolean = False

        Try
            ' Marshal the SecureString to unmanaged memory.
            passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password)

            ' Call LogonUser, passing the unmanaged (and decrypted) copy of
            ' the SecureString password.
            returnValue = LogonUser(userName, domainName, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle)


        Finally
            ' Zero-out and free the unmanaged string reference.
            Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr)

            ' Close the token handle.
            CloseHandle(tokenHandle)
        End Try

        ' Get the Last win32 Error and throw an exception.
        If Not returnValue AndAlso tokenHandle = IntPtr.Zero Then
            Dim [error] As Integer = Marshal.GetLastWin32Error()

            Throw New System.ComponentModel.Win32Exception([error])
        End If
        ' The token that is passed to the following constructor must 
        ' be a primary token in order to use it for impersonation.
        Dim newId As New WindowsIdentity(tokenHandle)

        Return newId.Impersonate()

    End Function
End Module
C#
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Text;

namespace SecureStringImpersonationExample
{

    class ImpersonationExample
    {

        // PInvoke into the Win32 API to provide access to the 
        // LogonUser and CloseHandle functions.
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        internal static extern bool LogonUser(String username, String domain, IntPtr password,
                int logonType, int logonProvider, ref IntPtr token);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);

        // Define the required LogonUser enumerations.
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_LOGON_INTERACTIVE = 2;


        static void Main(string[] args)
        {
            try
            {
                // Display the current user before impersonation.
                Console.WriteLine("Before impersonation: "
                    + WindowsIdentity.GetCurrent().Name);

                // Ask the user for a network domain.
                Console.Write("Please enter your domain:");

                string domain = Console.ReadLine();

                // Ask the user for a user name.
                Console.Write("Please enter your user name:");

                string username = Console.ReadLine();

                // Ask the user for a password.
                Console.Write("Please enter your password:");

                SecureString passWord = GetPassword();

                // Impersonate the account provided by the user.
                WindowsImpersonationContext userContext = ImpersonateUser(passWord, username, domain);

                // Display the current user after impersonation.
                Console.WriteLine("After impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.ReadLine();


        }

        public static SecureString GetPassword()
        {
            SecureString password = new SecureString();

            // get the first character of the password
            ConsoleKeyInfo nextKey = Console.ReadKey(true);

            while (nextKey.Key != ConsoleKey.Enter)
            {
                if (nextKey.Key == ConsoleKey.Backspace)
                {
                    if (password.Length > 0)
                    {
                        password.RemoveAt(password.Length - 1);

                        // erase the last * as well
                        Console.Write(nextKey.KeyChar);
                        Console.Write(" ");
                        Console.Write(nextKey.KeyChar);
                    }
                }
                else
                {
                    password.AppendChar(nextKey.KeyChar);
                    Console.Write("*");
                }

                nextKey = Console.ReadKey(true);
            }

            Console.WriteLine();

            // lock the password down
            password.MakeReadOnly();
            return password;
        }


        public static WindowsImpersonationContext ImpersonateUser(SecureString password, string userName, string domainName)
        {
            IntPtr tokenHandle = IntPtr.Zero;

            IntPtr passwordPtr = IntPtr.Zero;

            bool returnValue = false;

            try
            {
                // Marshal the SecureString to unmanaged memory.
                passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);

                // Call LogonUser, passing the unmanaged (and decrypted) copy of
                // the SecureString password.
                returnValue = LogonUser(userName, domainName, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);

            }
            finally
            {
                // Zero-out and free the unmanaged string reference.
                Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr);

                // Close the token handle.
                CloseHandle(tokenHandle);
            }

            // Get the Last win32 Error and throw an exception.
            if (!returnValue && tokenHandle == IntPtr.Zero)
            {
                int error = Marshal.GetLastWin32Error();

                throw new System.ComponentModel.Win32Exception(error);

            }
            // The token that is passed to the following constructor must 
            // be a primary token in order to use it for impersonation.
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);

            return newId.Impersonate();
        }
    }
}

Windows 98, Windows 2000 SP4, Windows Millennium, Windows Server 2003, Windows XP Media Center, Windows XP Professional x64, Windows XP SP2, Windows XP Starter Edition

.NET Framework no admite todas las versiones de cada plataforma. Para obtener una lista de las versiones admitidas, vea Requisitos del sistema.

.NET Framework

Compatible con: 2.0
Contenido de la comunidad   ¿Qué es Community Content?
Agregar contenido nuevo RSS  Anotaciones
Processing
© 2012 Microsoft. Reservados todos los derechos. Términos de uso | Marcas Registradas | Privacidad
Page view tracker