5

Bugün yeni oluşturulan ASP.NET uygulamasını sunucuya dağıtdık ve yakında uygulamanın çökmesine neden olan garip güvenlikle ilgili bir sorun olduğunu fark ettik. Bu dahili bir uygulamadır ve kullanıcıların kaynaklara nasıl erişeceklerini yönetmek için Kimliğe bürünme özelliğini kullanırız. Bununla birlikte, uygulama, kullanıcının tam denetime sahip olduğu bir klasöre erişmeyi kabul ettiğinde "Erişim Reddedildi" istisnası atar.Parallel.ForEach() değişiklikler Impersonation Context

istisna aslında bir AggregateException oldu ve bir liste numaralandırmak için Parallel.ForEach kullanır ve vücudun içinde, bu klasöre erişmeye çalıştığında bir yöntem atılmış ediliyordu, ancak bu noktada kimliğe bürünme Bağlam değişti ve işçi alır iş parçacığı, uygulama havuzunun kimliği olarak çalışır;

Before Loop: MyDomain\ImpersonatedUser 

Inside Loop: NT AUTHORITY\SYSTEM (Worker Thread 8) 
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 6) 
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 7) 
Inside Loop: NT AUTHORITY\SYSTEM (Worker Thread 9) 
Inside Loop: NT AUTHORITY\SYSTEM (Worker Thread 10) 
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 7) 
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 6) 
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 7) 

gibi: Ben app çalıştırdığınızda

string before = WindowsIdentity.GetCurrent().Name; 
Debug.WriteLine("Before Loop: {0}", before); 

Parallel.ForEach(myList, currentItem => 
{ 
    string inside = WindowsIdentity.GetCurrent().Name; 
    Debug.WriteLine("Inside Loop: {0} (Worker Thread {1})", inside, Thread.CurrentThread.ManagedThreadId); 
}); 

, bu yazdırılır alır budur:

Bunu doğrulamak için, daha önce ve Parallel.ForEach gövdesi içinde işlem kimliği baktı Gördüğünüz gibi, bazı iş parçacıklarının kimliğine bürünmüş kimlik ve bazı uygulama havuzu (bu durumda, LocalSystem) olarak çalışıyor ve bir desen gibi görünmüyor. Call Stack penceresindeki bir önceki çerçeve de yönetilmeyen kernel32.dll'a gider, bu da beni CLR'nin işletim sistemine devretmeden önce bağlamı doğrulamadığını düşünmemi sağlar.

Bunun neden olduğu hakkında bir fikriniz var mı? Bu bilinen bir sorun/hata mı? Task sınıfın aksine

cevap

3

, Parallel şu anda (sırayla WindowsIdentity tutan SecurityContext yakalar olan) üzerinde çalıştırıyorsanız ExecutionContext tarafından algılanmadığını etmez. Mevcut Thread içindeki kullanılabilir olanı kullanır.

açıkça istenen bağlamı yakalamak zorunda

:

IntPtr token = WindowsIdentity.GetCurrent().Token; 

Parallel.ForEach(myList, currentItem => 
{ 
    using (WindowsIdentity.Impersonate(token)) 
    { 
     string inside = WindowsIdentity.GetCurrent().Name; 
     Debug.WriteLine("Inside Loop: {0} (Worker Thread {1})", inside, Thread.CurrentThread.ManagedThreadId); 
    } 
}); 
+0

Ama neden aslında bir model gibi görünmüyor? – abatishchev

+0

Çok emin değilim. Daha önce bu şekilde sorular gördüm. * Beklenilen * davranış * olması gereken bir özellik gibi görünüyor. –

+0

Evet Windows Server.GetCurrent() işlevini kullanarak bir geçici çözüm olarak Impersonate() 'ı kullanıyorum ama hala neden iş parçacıkları arasında bir tutarsızlık olduğunu anlamıyorum. 'SecurityContext' yakalanmıyorsa, iş parçacıklarından bazıları hala kimliğine bürünmüş kimlik olarak çalışıyor? Daha fazlası varmış gibi hissediyorum. – PoweredByOrange

0

Windows bütün Impersonation konsepti parçacığı başına kavramdır. Yeni bir iş parçacığı oluşturulduğunda, sürecin 'ayrıcalık belirtecini miras aldığını görürsünüz. Ancak, işlemlerinden farklı olarak iş parçacığı, ayrıca bir kimliğe bürünme belirtecine sahiptir. WindowsIdentity.Impersonate (belirteç) 'i çağırdığınızda, çağrı iş parçacığı.

Ayrıca, Kimliğe bürünmüş olarak adlandırdığınızda, iş parçacığının birincil belirteç işaretçisini varsayılan "işlemin" birincil belirteç yerine, kimliğe bürünme belirtecini gösterecek şekilde ayarlamanız gerekir.

WinAPI'de biraz daha fazla bilgi ve bilgi sahibi olmanız, hizmetinizde olan bitenin 'un beklenen davranış olduğunu olduğunu bilmenizi sağlayacaktır.

+2

Ve biraz daha az snark dünyayı daha iyi bir yer haline getiriyor ve beklenen davranış olmalı. – Loofer