ASP.NET web handler run command as requesting user - asp.net

From a web handler (xxx.ashx) I need to run a command as the same user using the web page and sending the request. I have IIS setup using impersonation, have code in my .ashx that shows it is impersonating the user, and then I use the C# Process.start() to run the command. (It's a .cmd file I am running)
The problem is that the .cmd file runs as the user assigned to the Application Pool and not the web user. I even tried this code:
WindowsImpersonationContext impersonationContext = ((WindowsIdentity)System.Security.Principal.WindowsIdentity.GetCurrent()).Impersonate();
Could this be an issue: I wrote the .ashx file and put just it under the IIS wwwroot/myapp folder and call it from a URL from a web browser. I have setup the Application Pool using the DefaultAppPool user and an OS user, but no difference.
I'm a novice with IIS & ASP too so this is like working in a black box.

We had to use the native windows method: CreateProcessAsUser(), and had to call DuplicateTokenEx() to duplicate the security token.
<%# WebHandler Language="C#" Class="batchRunSAS" %>
using System;
using System;
using System.IO;
using System.Web;
using System.Diagnostics;
using System.Security.Principal;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using System.ComponentModel;
public class batchRun : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
//Call DuplicateTokenEx
//https://msdn.microsoft.com/en-us/library/ms682429(VS.85).aspx
//http://stackoverflow.com/questions/9095909/createprocessasuser-creating-window-in-active-session
Process process = null;
process = NativeMethods.CreateProcessAsUser("C:\\temp\\test.exe");
}
public bool IsReusable
{
get { return false; }
}
[SuppressUnmanagedCodeSecurity]
class NativeMethods
{
[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public Int32 dwProcessID;
public Int32 dwThreadID;
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public Int32 Length;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
public enum SECURITY_IMPERSONATION_LEVEL
{
SecurityAnonymous,
SecurityIdentification,
SecurityImpersonation,
SecurityDelegation
}
public enum TOKEN_TYPE
{
TokenPrimary = 1,
TokenImpersonation
}
public const int GENERIC_ALL_ACCESS = 0x10000000;
public const int CREATE_NO_WINDOW = 0x08000000;
[
DllImport("kernel32.dll",
EntryPoint = "CloseHandle", SetLastError = true,
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)
]
public static extern bool CloseHandle(IntPtr handle);
[
DllImport("advapi32.dll",
EntryPoint = "CreateProcessAsUser", SetLastError = true,
CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)
]
public static extern bool
CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandle, Int32 dwCreationFlags, IntPtr lpEnvrionment,
string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo,
ref PROCESS_INFORMATION lpProcessInformation);
[
DllImport("advapi32.dll",
EntryPoint = "DuplicateTokenEx")
]
public static extern bool
DuplicateTokenEx(IntPtr hExistingToken, Int32 dwDesiredAccess,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
Int32 ImpersonationLevel, Int32 dwTokenType,
ref IntPtr phNewToken);
public static Process CreateProcessAsUser(string filename, string args)
{
var hToken = WindowsIdentity.GetCurrent().Token;
var hDupedToken = IntPtr.Zero;
var pi = new PROCESS_INFORMATION();
var sa = new SECURITY_ATTRIBUTES();
sa.Length = Marshal.SizeOf(sa);
try
{
if (!DuplicateTokenEx(
hToken,
GENERIC_ALL_ACCESS,
ref sa,
(int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
(int)TOKEN_TYPE.TokenPrimary,
ref hDupedToken
))
throw new Win32Exception(Marshal.GetLastWin32Error());
var si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = "";
var path = Path.GetFullPath(filename);
var dir = Path.GetDirectoryName(path);
// Revert to self to create the entire process; not doing this might
// require that the currently impersonated user has "Replace a process
// level token" rights - we only want our service account to need
// that right.
using (var ctx = WindowsIdentity.Impersonate(IntPtr.Zero))
{
if (!CreateProcessAsUser(
hDupedToken,
path,
string.Format("\"{0}\" {1}", filename.Replace("\"", "\"\""), args),
ref sa, ref sa,
false, 0, IntPtr.Zero,
dir, ref si, ref pi
))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return Process.GetProcessById(pi.dwProcessID);
}
finally
{
if (pi.hProcess != IntPtr.Zero)
CloseHandle(pi.hProcess);
if (pi.hThread != IntPtr.Zero)
CloseHandle(pi.hThread);
if (hDupedToken != IntPtr.Zero)
CloseHandle(hDupedToken);
}
}
}
}

Related

Display all the user's files using Microsoft Graph API not working

I have created one .net website application and i have added dlls and codes same like below reference video.
https://www.youtube.com/watch?v=KNJUrCHv6no&list=PLWZJrkeLOrbZ8Gl8zsxUuXTkmytyiEGSh&index=5
I have created one free Microsoft account with free subscription my id like (xxxx#outlook.com) and i registered my application same in azure same as
https://www.youtube.com/watch?v=k7nnvdNgfOE&list=PLWZJrkeLOrbZ8Gl8zsxUuXTkmytyiEGSh&index=4 this video.
But its not working for me. request.GetAsync().Result takes more time and request time out issue shown. i added my code below. please suggest.
default.aspx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.Identity.Client;
using Microsoft.Graph;
using Microsoft.Extensions.Configuration;
using Helpers;
using System.Security;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var config = LoadAppSettings();
if (config == null)
{
iserror.Text = "config error";
return;
}
try
{
var userName = ReadUsername();
var userPassword = ReadPassword();
var client = GetAuthenticatedGraphClient(config, userName, userPassword);
var request = client.Me.Drive.Root.Children.Request();
var results = request.GetAsync().Result;
foreach (var file in results)
{
}
}
catch { iserror.Text = "config file exist. azure error"; }
}
private static SecureString ReadPassword()
{
var securePassword = "xxxxxxx";
SecureString password = new SecureString();
foreach (char c in securePassword)
password.AppendChar(c);
return password;
}
private static string ReadUsername()
{
string username;
username = "xxx#outlook.com";
return username;
}
private static GraphServiceClient GetAuthenticatedGraphClient(IConfigurationRoot config, string userName, SecureString userPassword)
{
var authenticationProvider = CreateAuthorizationProvider(config, userName, userPassword);
var graphClient = new GraphServiceClient(authenticationProvider);
return graphClient;
}
private static IAuthenticationProvider CreateAuthorizationProvider(IConfigurationRoot config, string userName, SecureString userPassword)
{
var clientId = config["applicationId"];
var authority = "https://login.microsoftonline.com/" + config["tenantId"] + "/v2.0";
List<string> scopes = new List<string>();
scopes.Add("User.Read");
scopes.Add("Files.Read");
var cca = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(authority)
.Build();
return MsalAuthenticationProvider.GetInstance(cca, scopes.ToArray(), userName, userPassword);
}
private static IConfigurationRoot LoadAppSettings()
{
try
{
string asas = HttpContext.Current.Server.MapPath("");
var config = new ConfigurationBuilder()
.SetBasePath(asas)
.AddJsonFile("appsettings.json", false, true)
.Build();
if (string.IsNullOrEmpty(config["applicationId"]) ||
string.IsNullOrEmpty(config["tenantId"]))
{
return null;
}
return config;
}
catch (System.IO.FileNotFoundException)
{
return null;
}
}
}
MsalAuthenticationProvider.cs
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Graph;
namespace Helpers
{
public class MsalAuthenticationProvider : IAuthenticationProvider
{
private static MsalAuthenticationProvider _singleton;
private IPublicClientApplication _clientApplication;
private string[] _scopes;
private string _username;
private SecureString _password;
private string _userId;
private MsalAuthenticationProvider(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
{
_clientApplication = clientApplication;
_scopes = scopes;
_username = username;
_password = password;
_userId = null;
}
public static MsalAuthenticationProvider GetInstance(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
{
if (_singleton == null)
{
_singleton = new MsalAuthenticationProvider(clientApplication, scopes, username, password);
}
return _singleton;
}
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
var accessToken = await GetTokenAsync();
request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
}
public async Task<string> GetTokenAsync()
{
if (!string.IsNullOrEmpty(_userId))
{
try
{
var account = await _clientApplication.GetAccountAsync(_userId);
if (account != null)
{
var silentResult = await _clientApplication.AcquireTokenSilent(_scopes, account).ExecuteAsync();
return silentResult.AccessToken;
}
}
catch (MsalUiRequiredException) { }
}
var result = await _clientApplication.AcquireTokenByUsernamePassword(_scopes, _username, _password).ExecuteAsync();
_userId = result.Account.HomeAccountId.Identifier;
return result.AccessToken;
}
}
}
appsettings.json*
{
"tenantId": "xxxx",
"applicationId": "xxxx"
}
It looks like you're running into the standard deadlock
situation where async method is trying to continue thread which is
blocked by the call to Result. Try using async Task test methods
instead of void .
Note: And especially in user interactions one should be careful of blocking
by using .Result calls on the main thread, as this type of call
can lock-up your application for further user interaction.
Try by avoiding the use of Result in the call.
var results = await request.GetAsync();
and do check if you need to add async to all the methods .
Also check this c# - When querying drive items using Microsoft
Graph- Stack Overflow that is relatable.
Also if above doesn’t resolve , try also to set the Timeout to a
higher value
example:to one hour:
graphServiceClient.HttpProvider.OverallTimeout = TimeSpan.FromHours(1);
Please check these below useful references:
c# - 'await' works, but calling task.Result hangs/deadlocks - Stack
Overflow
How To Access Microsoft Graph API In Console Application
(c-sharpcorner.com)

How do I catch unhandled exceptions in ASP .NET Core 2.0 before the page is rendered?

I am trying to integrate sentry into my asp .net core app. I can't seem to find a straight answer how to catch the exception before the server throws 500 in asp net core 2.0.
I've searched official docs. Non-development mode.
Here is an example of exception handling middleware. It returns custom verbiage with the 500 status code.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Serilog;
using System;
using System.Diagnostics;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Foo
{
public class ExceptionHandlingMiddleware
{
private readonly RequestDelegate next;
public ExceptionHandlingMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
await handleExceptionAsync(context, ex);
}
}
private static async Task handleExceptionAsync(HttpContext context, Exception exception)
{
string errorCode = calculateErrorCode(context.TraceIdentifier);
string message = string.Format("An unhandled exception occurred; please contact the help desk with the following error code: '{0}' [{1}]", errorCode, context.TraceIdentifier);
Log.Error(exception, message);
context.Response.ContentType = "text/plain";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
await context.Response.WriteAsync(message);
}
private static string calculateErrorCode(string traceIdentifier)
{
const int ErrorCodeLength = 6;
const string CodeValues = "BCDFGHJKLMNPQRSTVWXYZ";
MD5 hasher = MD5.Create();
StringBuilder sb = new StringBuilder(10);
byte[] traceBytes = hasher.ComputeHash(Encoding.UTF8.GetBytes(traceIdentifier));
int codeValuesLength = CodeValues.Length;
for (int i = 0; i < ErrorCodeLength; i++)
{
sb.Append(CodeValues[traceBytes[i] % codeValuesLength]);
}
return sb.ToString();
}
}
public static class ExceptionHandlingMiddlewareExtensions
{
public static IApplicationBuilder UseApiExceptionHandler(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ExceptionHandlingMiddleware>();
}
}
}
Configure in Startup.cs
app.UseApiExceptionHandler();

ASP.NET impersonation works only when a user is specified in the web.config

First, I apologize is this a duplicate, but I really couldn't find a similar problem anywhere.
The situation is I'm attempting to use the impersonation feature in asp.net to retrieve a file located on a network directory. When I specify the user in the web.config, it works fine:
<identity impersonate="true" userName="contoso\Jane" password="********" />
However, when I try using the following, I recieve a prompt to login to the site, which I'm never able to do successfully.
<identity impersonate="true"/>
My understanding of the latter example is that it will attempt to impersonate with the windows credential of whomever is currently viewing the page (via windows authentication). Is this not correct?
I should note, I do have windows authentication working properly in other areas of the app.
Thanks
EDIT
I should also mention, this is running on II6... and it just "feels" like a configuration issue...
I would go a other way with a extra class Impersonate.cs and You need a user, a password and a Domain.
Imperosnate.cs :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Security;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System.Web;
namespace [YourProgramName] //You must change it
{
public class Impersonate
{
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, out int phToken);
[DllImport("kernel32.dll")]
private static extern int FormatMessage(int dwFlags, string lpSource, int dwMessageId, int dwLanguageId,
StringBuilder lpBuffer, int nSize, string[] Arguments);
private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
private const int LOGON32_PROVIDER_DEFAULT = 0;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
private static WindowsImpersonationContext winImpersonationContext = null;
public static void ImpersonateUser(string domain, string userName, string password)
{
//Benutzer einloggen
int userToken = 0;
bool loggedOn = (LogonUser(userName, domain, password, LOGON32_LOGON_NETWORK_CLEARTEXT,
LOGON32_PROVIDER_DEFAULT, out userToken) != 0);
if (loggedOn == false)
{
int apiError = Marshal.GetLastWin32Error();
StringBuilder errorMessage = new StringBuilder(1024);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, null, apiError, 0, errorMessage, 1024, null);
throw new Exception(errorMessage.ToString());
}
WindowsIdentity identity = new WindowsIdentity((IntPtr)userToken);
winImpersonationContext = identity.Impersonate();
}
public static void UndoImpersonation()
{
if (winImpersonationContext != null)
{
winImpersonationContext.Undo();
}
}
}
}
Use it in your program:
string Admin = Properties.Settings.Default.Admin;
string AdminPassword = Properties.Settings.Default.AdminPassword;
string Domain = Properties.Settings.Default.Domain;
Impersonate.ImpersonateUser(Domain , Admin , AdminPassword);
//Your Code as the new User
Impersonate.UndoImpersonation();
hope it is what you search ^^

Calling WindowsIdentity.Impersonate does nothing

I'm using the following Microsoft example. Every time the WindowsIdentity instance calls .Impersonate(), nothing happens. No error, no impersonation.
Both before and after the call, the current identity is always the AppPool identity.
I've also tried another example found online, the Impersonator class, and the same thing happens.
The only modification I've made to those examples is changing LOGON32_LOGON_INTERACTIVE to LOGON32_LOGON_NETWORK in the LogOnUser call, since using Interactive always returned a 0 error.
It's an ASP.NET 4.0 app running on a Win2k8 server trying to impersonate a user in AD.
EDIT:
I hadn't mentioned this originally, but I modified the Microsoft example and turned it into a class so that I can could it from my ASP.NET app. I also have impersonate=true in web.config.
I eventually found a helper class where I had done something similar a couple of years ago. The helper implements IDisposable, so just wrap your file access code in a "using" like this:-
using (Impersonate imp = new Impersonate())
{
// Code in here will run under the identity specified in the helper
}
And here is the code for the helper class (I've removed the "usings" to save some space). You'll notice the user account is hardcoded in the constructor:
internal class Impersonate : IDisposable
{
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
private bool _disposed = false;
private WindowsImpersonationContext _context = null;
[DllImport("advapi32.dll")]
private static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
internal Impersonate()
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
string domain = "<whatever>";
string username = "<whatever>";
string password = "<whatever>";
try
{
if (RevertToSelf())
{
if (LogonUserA(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
_context = tempWindowsIdentity.Impersonate();
}
}
}
}
finally
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
if (tokenDuplicate != IntPtr.Zero)
{
CloseHandle(tokenDuplicate);
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose any managed resources here.
}
// Stop the impersonation.
_context.Undo();
_disposed = true;
}
}
}
Give it a go and let me know how you get on...
Andrew
The example you link is for a console application. If you have an ASP.Net web application where you want your code to be executed under the security context of the visitor you can enable ASP.Net impersonation in the IIS authentication settings (in the IIS manager MMC snap in).
Giving write access to the App_Data folder for the Users group fixed the issue. Not sure what that has to do with impersonation though.

Impersonation with Win32 API to access network share versus reading network share with Windows Explorer?

I have a web application that impersonates using the Win32 API. I recently returned from a trip to find the part of the application that impersonates failing.
The reason for the impersonation is that there is a network share that is used for a specific purpose. When my web application accesses that network share, it must impersonate a special account. For the sake of discussion, the uid is "Bob", the password is "1234", and the domain is "home".
Two weeks ago, I wrote my program to use the Win32 API to impersonate Bob and all was well. Now, the Win32 API indicates logon failure. I'm having trouble figuring out what could have changed. To be specific, the server indicates that it fails to impersonate Bob. The error occurs before the server actually tries to access a network share.
The bizarre thing is that if I connect to my web server with MSTSC, I can click on "Map Network Drive" in the Windows Explorer and access the files using Bob#home and password 1234. (I enter the uid and password by clicking on "Connect using a different user name" in the "Map Network Drive" dialog)
It seems that something different must be happening when I try to access my network share with impersonation versus using the Windows Explorer.
What is that difference?
Update: I feel like the answer to this problem is that there is some sort of logon permission that is being denied that is somehow not involved when I access my files through Windows Explorer.
Make sure that you're using the UNC path to access the folder:
string path = #"\\server\folder";
I don't know what your impersonation class looks like, but here's a class that I use for similar tasks:
/// <summary>
/// Leverages the Windows API (advapi32.dll) to programmatically impersonate a user.
/// </summary>
public class ImpersonationContext : IDisposable
{
#region constants
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
#region global variables
private WindowsImpersonationContext impersonationContext;
private bool impersonating;
#endregion
#region unmanaged code
[DllImport("advapi32.dll")]
private static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
#endregion
#region constructors
public ImpersonationContext()
{
impersonating = false;
}
/// <summary>
/// Overloaded constructor and begins impersonating.
/// </summary>
public ImpersonationContext(string userName, string password, string domain)
{
this.BeginImpersonationContext(userName, password, domain);
}
#endregion
#region impersonation methods
/// <summary>
/// Begins the impersonation context for the specified user.
/// </summary>
/// <remarks>Don't call this method if you used the overloaded constructor.</remarks>
public void BeginImpersonationContext(string userName, string password, string domain)
{
//initialize token and duplicate variables
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
using (WindowsIdentity tempWindowsIdentity = new WindowsIdentity(tokenDuplicate))
{
//begin the impersonation context and mark impersonating true
impersonationContext = tempWindowsIdentity.Impersonate();
impersonating = true;
}
}
}
}
//close the handle to the account token
if (token != IntPtr.Zero)
CloseHandle(token);
//close the handle to the duplicated account token
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
}
/// <summary>
/// Ends the current impersonation context.
/// </summary>
public void EndImpersonationContext()
{
//if the context exists undo it and dispose of the object
if (impersonationContext != null)
{
//end the impersonation context and dispose of the object
impersonationContext.Undo();
impersonationContext.Dispose();
}
//mark the impersonation flag false
impersonating = false;
}
#endregion
#region properties
/// <summary>
/// Gets a value indicating whether the impersonation is currently active.
/// </summary>
public bool Impersonating
{
get
{
return impersonating;
}
}
#endregion
#region IDisposable implementation
~ImpersonationContext()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (impersonationContext != null)
{
impersonationContext.Undo();
impersonationContext.Dispose();
}
}
}
#endregion
}
Using ImpersonationContext:
using (ImpersonationContext context = new ImpersonationContext("user", "password", "domain"))
{
if (context.Impersonating)
{
Process.Start(#"/Support/SendFax/SendFax.exe");
}
}

Resources