Marshal.SecureStringToGlobalAllocUnicode(SecureString) 메서드
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
중요
이 API는 CLS 규격이 아닙니다.
관리되는 SecureString 개체의 콘텐츠를 관리되지 않는 메모리로 복사합니다.
public:
static IntPtr SecureStringToGlobalAllocUnicode(System::Security::SecureString ^ s);
public static IntPtr SecureStringToGlobalAllocUnicode (System.Security.SecureString s);
[System.CLSCompliant(false)]
public static IntPtr SecureStringToGlobalAllocUnicode (System.Security.SecureString s);
[System.Security.SecurityCritical]
public static IntPtr SecureStringToGlobalAllocUnicode (System.Security.SecureString s);
static member SecureStringToGlobalAllocUnicode : System.Security.SecureString -> nativeint
[<System.CLSCompliant(false)>]
static member SecureStringToGlobalAllocUnicode : System.Security.SecureString -> nativeint
[<System.Security.SecurityCritical>]
static member SecureStringToGlobalAllocUnicode : System.Security.SecureString -> nativeint
Public Shared Function SecureStringToGlobalAllocUnicode (s As SecureString) As IntPtr
매개 변수
복사할 관리되는 개체입니다.
반환
-
IntPtr
nativeint
관리되지 않는 메모리에서 s
가 복사된 주소이거나 s
가 길이가 0인 SecureString 개체인 경우 0입니다.
- 특성
예외
s
매개 변수가 null
인 경우
사용 가능한 메모리가 부족한 경우
예제
다음 예제에서는 관리 LogonUser
되지 않는 함수와 함께 메서드를 사용하여 SecureStringToGlobalAllocUnicode 클래스로 가장 SecureString 을 수행하는 방법을 보여 줍니다. 그런 다음 이 예제에서는 메서드를 ZeroFreeGlobalAllocUnicode 사용하여 관리되지 않는 문자열 참조를 0으로 해제하고 해제합니다.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
class Example
{
// Define the Windows 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()
{
// Display the current user before impersonation.
Console.WriteLine("Before impersonation: {0}",
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.
try {
WindowsImpersonationContext userContext =
ImpersonateUser(passWord, username, domain);
// Display the current user after impersonation.
Console.WriteLine("After impersonation: {0}",
WindowsIdentity.GetCurrent().Name);
}
catch (ArgumentException e) {
Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message);
}
catch (Win32Exception e) {
Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message);
}
finally {
passWord.Dispose();
}
}
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;
int error = 0;
// Marshal the SecureString to unmanaged memory.
passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);
// Pass LogonUser the unmanaged (and decrypted) copy of the password.
returnValue = LogonUser(userName, domainName, passwordPtr,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);
if (!returnValue && tokenHandle == IntPtr.Zero)
error = Marshal.GetLastWin32Error();
// Perform cleanup whether or not the call succeeded.
// Zero-out and free the unmanaged string reference.
Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr);
// Close the token handle.
CloseHandle(tokenHandle);
// Throw an exception if an error occurred.
if (error != 0) {
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();
}
}
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Imports System.Security
Imports System.Security.Principal
Module Example
' 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)
' Display the current user before impersonation.
Console.WriteLine("Before impersonation: {0}",
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.
Try
Dim userContext As WindowsImpersonationContext =
ImpersonateUser(passWord, username, domain)
' Display the current user after impersonation.
Console.WriteLine("After impersonation: {0}",
WindowsIdentity.GetCurrent().Name)
Catch e As ArgumentException
Console.WriteLine(e.Message)
Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message)
Catch e As Win32Exception
Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message)
Finally
passWord.Dispose()
End Try
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
Dim err As Integer = 0
' Marshal the SecureString to unmanaged memory.
passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password)
' Pass LogonUser the unmanaged (and decrypted) copy of the password.
returnValue = LogonUser(userName, domainName, passwordPtr,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
tokenHandle)
If Not returnValue AndAlso tokenHandle = IntPtr.Zero Then
err = Marshal.GetLastWin32Error()
End If
' Perform cleanup whether or not the call succeeded.
' Zero-out and free the unmanaged string reference.
Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr)
' Close the token handle.
CloseHandle(tokenHandle)
' Throw an exception if an error occurred.
If err <> 0 Then
Throw New System.ComponentModel.Win32Exception(err)
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
설명
이 SecureStringToGlobalAllocUnicode 메서드는 사용자 지정 마샬링에 유용하거나 관리 코드와 관리되지 않는 코드를 혼합할 때 사용할 수 있습니다. 이 메서드는 문자열에 필요한 관리되지 않는 메모리를 할당하므로 항상 메서드를 호출하여 메모리를 해제합니다 ZeroFreeGlobalAllocUnicode .