| Impersonation |
|
در مواقعي كه code شما با Permissionهاي كاربر خاصي در حال اجراست و آن كاربر اجازه انجام اقدام خاصي را ندارد، مي توانيد با استفاده از Impersonation قسمتي از Code را با استفاده از Permissionهاي كاربر ديگر اجرا كنيد. اين كار بيشتر در ASP.net رايج است و دليل آن Permission هاي محدود كاربر ASP.net يا Network Service است. براي اين كار بايستي ابتدا تعداري از dll هاي سيستمي را Import كنيد:
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser(
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);
دو Constant را نيز براي در نظر گرفتن نوع LogIn كاربر و نيز Provider آن تعريف مي كنيم. همچنين براي نگهداري WindowsImpersonationContext حاصل ار Impersonation متغيري نيز از اين نوع تعريف مي كنيم:
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
private WindowsImpersonationContext impersonationContext = null;
حال براي راحتي و سهولت بيشتر در استفاده از Code اي كه مي نويسيم، متدي به نام ImpersonateUser را تعريف و دستورات مربوطه را در داخل اين متد مي نويسيم:
private void ImpersonateUser(
string userName,
string domain,
string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if (RevertToSelf())
{
if (LogonUser(
userName,
domain,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
finally
{
if (token != IntPtr.Zero)
{
CloseHandle(token);
}
if (tokenDuplicate != IntPtr.Zero)
{
CloseHandle(tokenDuplicate);
}
}
بايد اين را نيز در نظر بگيريم كه پس از Impersonation و انجام اقدامات لازم، به دلايل امنيتي بايستي حتماً كاربر LogIn شده را LogOut كنيم. بنابراين متدي نيز به نام UndoImpersonation براي اين كار مي نويسيم:
private void UndoImpersonation()
{
if (impersonationContext != null)
{
impersonationContext.Undo();
}
}
و در نهايت، نحوه ي استفاده از Impersoantion به اين صورت خواهد بود كه ابتدا متد ImpersonateUser را با پارماتر هاي مناسب فراخواني كرده، پس از انجام اقداماتي كه نياز به Impersonation دارند، با فراخواني UndoImpersonation همه چيز را به حالت عادي باز مي گردانيم:
ImpersonateValidUser(
AdminUserName,
Domain,
AdminPassword );
// do some thing ...
UndoImpersonation();
كاربري كه براي Impersoantion انتخاب مي كنيد بايستي حتماً Permissionهاي لازمه را داشته باشد و نيز درصورتي كه سيستم اجرا كننده اين Code تحت كنترل Domain Controller نيست و يا حتي اسم Domain را نمي دانيد، مي توانيد اين پارامتر را با String.Empty مقدار دهيد.
|