Return to
HomePage
Question: Can impersonation be used with Forms authentication?
Answer:
Yes, you can either use protocol transition, if you're running on Windows Server 2003, or you can call
LogonUser.
If you need to delegate the original caller's identity on machines that are not running Windows Server 2003, or where you cannot use Kerberos authentication, then you need to use the
LogonUser API.
To use the LogonUser API:
- Use Forms authentication to obtain the username, password and domain from the user.
- Grant the Act as part of the operating system privilege (TCB) to the account used to run ASP.NET on the Web server (the Network Service account by default).
- Add a DllImport definition for LogonUser (advapi32.dll) and CloseHandle (kernel32.dll)
- Call the LogonUser method, passing the user ID, password, and domain. Also request a network logon type. This method returns the impersonation token as an output parameter.
- Use the impersonation token to create a Windows identity and impersonate that identity.
- When you have completed your resource access, remove the impersonation token from the current thread and call CloseHandle to close the impersonation token.
For example :
using [System.Runtime.InteropServices;]
…
// Declare the logon types as constants
const long LOGON32_LOGON_NETWORK = 3;
// Declare the logon providers as constants
const long LOGON32_PROVIDER_DEFAULT = 0;
[DllImport("advapi32.dll",EntryPoint = "LogonUser")]
private static extern bool [LogonUser(]
string lpszUsername,
string lpszDomain,
string lpszPassword,
int [dwLogonType,]
int [dwLogonProvider,]
ref [IntPtr] phToken);
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public extern static bool [CloseHandle(IntPtr] handle);
private void [ImpersonateAndUse(string] Username,
string Password,
string Domain)
{
[IntPtr] token = new [IntPtr(0);]
token = [IntPtr.Zero;]
// Call [LogonUser] to obtain a handle to an access token.
bool returnValue = [LogonUser(Username,] Domain,Password,
(int)LOGON32_LOGON_NETWORK,
(int)LOGON32_PROVIDER_DEFAULT,
ref token);
if (false == returnValue)
{
int ret = [Marshal.GetLastWin32Error();]
string strErr = String.Format("LogonUser failed with error code : {0}", ret);
throw new [ApplicationException(strErr,] null);
}
[WindowsIdentity] newId = new [WindowsIdentity(token);]
[WindowsImpersonationContext] impersonatedUser = newId.Impersonate();
try
{
// do the operations using original user security context
}
finally
{
// stop impersonating
impersonatedUser.Undo();
[CloseHandle(tokenHandle);] // From where did this variable "tokenHandle" came from?
}
}
Return to
HomePage