This project is read-only.

Consider Using LogonUser API, If Your WCF Service Cannot be Trusted for Delegation

- J.D. Meier, Carlos Farre, Jason Taylor, Prashant Bansode, Steve Gregersen, Madhu Sundararajan, Rob Boucher

Use the Win32 LogonUser API (via P/Invoke) to create delegation-level impersonation tokens, but only when your WCF service cannot be trusted for delegation, because this option forces you to store user name and passwords on your WCF Service.

Use the basic authentication mode to get the original user’s impersonation token so that you will have access to the username and password. You can then get the impersonation token using the LogonUser API. For Service accounts you will have to store the username and password securely, and then using the LogonUser API to get the impersonation token.

The following code example shows how the LogonUser API is used for impersonation:
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(token);
  }
}

Additional Resources

Last edited Jun 12, 2008 at 10:40 PM by prashantbansode, version 1

Comments

No comments yet.