.Net Core (1.0+) Platformunda Kimliğe Bürünme (Impersonation)Beğen
Impersonation kimliğe bürünme anlamına gelir. Windows Service veya Web uygulaması gibi sistem, IIS veya farklı genel bir kullanıcıya ait olarak çalışan uygulamalar mevcuttur. Bu uygulamalar üzerinden spesifik bir windows kullanıcısı yetkilendirmesi ile işlem yapmak isteyebilirsiniz. Dosya okuma ve yazma buna bir örnektir. Yazmak istediğiniz (ağdaki veya lokal) klasör sadece belli bir kullanıcıya okuma-yazma izni vermiş olabilir ve sizin de o kullanıcı kimliği ile işlem yapmanız gerekebilir. .Net Framework üzerinde bu işi WindowsImpersonationContext ile yapabiliyorduk ancak gördüğüm kadarı ile .Net Core ve sonrası artık bu yapıyı desteklemiyor.
.NetCore platformunda herhangi bir kullanıcıya bürünerek işlem yapabilmek için WindowsIdentity.RunImpersonated metoduna aksiyon (delege) geçebiliyoruz. Ben aşağıdaki gibi bir yardımcı sınıf kullanıyorum.
xxxxxxxxxx
public class ImpersonationHelper
{
private const int Logon32NewCredentials = 9;
private const int Logon32ProviderDefault = 0;
private const int Logon32LogonInteractive = 2; //This parameter causes LogonUser to create a primary token.
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeAccessTokenHandle phToken);
public static void RunImpersonated(string domainName, string userName, string password, Action action)
{
var returnValue = LogonUser(userName, domainName, password,
Logon32NewCredentials, Logon32ProviderDefault,
out var safeAccessTokenHandle);
if (!returnValue)
{
var retCode = Marshal.GetLastWin32Error();
throw new ApplicationException($"Could not impersonate the elevated user. LogonUser returned error code {retCode}.");
}
Debug.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name);
// to run as unimpersonated, 'SafeAccessTokenHandle.InvalidHandle' instead of 'safeAccessTokenHandle'
WindowsIdentity.RunImpersonated(
safeAccessTokenHandle,
() =>
{
Debug.WriteLine("During impersonation: " + WindowsIdentity.GetCurrent().Name);
action?.Invoke();
}
);
Debug.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
}
}
Yukarıda özetle; advapi32.dll kütüphanesi aracılığı ile interop yaparak kullanıcı ve şifre bilgisiyle istediğimiz windows kullanıcısı için tokenhandle alıyoruz. Sonrasında bu token aracılığı kimliğe bürünerek istediğimiz aksiyonu gerçekleştiriyoruz. Bu yardımcı sınıfı örneğin aşağıdaki gibi kullanabilirim:
xxxxxxxxxx
ImpersonationHelper.RunImpersonated(domain, username, password, () =>
{
var content = File.ReadAllBytes(path);
File.WriteAllBytes(anotherpath, content)
try //try delete
{
File.Delete(path);
}
catch (Exception ex)
{
//log exception
}
});
Yukarıda gerçekleştirilen dosya okuma, yazma, silme işlemleri belirttiğim windows domain-kullanıcı yetkilendirmesi ile gerçekleşecektir. İlgili Microsoft dokümantasyonuna bu link üzerinden ulaşabilirsiniz.