2013-02-01 5 views
5

Mam 2 aplikacje ASP.NET MVC 3. Używam podszywania się za pośrednictwem pliku web.config, aby umożliwić mi wysłanie zapytania do Active Directory w celu uzyskania szczegółowych informacji o użytkowniku. Aplikacja korzysta z uwierzytelniania systemu Windows i nie zezwala na anonimowych użytkowników. Jedna aplikacja to główna aplikacja, w której użytkownik wykonuje swoje zadania. Drugi pozwala użytkownikowi skonfigurować innych użytkowników, aby wyglądali jak oni w aplikacji pierwszej.Personifikacja, Active Directory i problemy z "użytkownikiem nie ma uprawnień do xxxx"

Użytkownik Test'S otrzymuję następujący błąd:

SQL1092N "<DOMAIN ID>" does not have the authority to perform the requested command. 

Dzieje się tak po tym, jak wysłać żądanie internetową z mojego pierwotnego wniosku do jednego wtórnego. Aby to zadziałało, musiałem uczynić żądanie personifikacją rzeczywistego użytkownika, a nie tożsamością, której aplikacja używa do personifikacji. To jest właściwie pytanie, które napisałem i odpowiedziałem. To tutaj: How do I call an MVC Action via a WebRequest and validate the request through Active Directory?

Pod koniec tego kodu, wzywam:

impersonationContext.Undo(); 

Jest po to żądanie WWW odbywa się, że podstawowym aplikacja próbuje dostępu do bazy danych, a teraz wydaje się, że powyższe wezwanie cofnął podszywanie się pod aplikację, więc próba użytkownika, która spowodowała otwarcie połączenia z bazą danych, zakończyła się niepowodzeniem. Przynajmniej to moja robocza teoria po całym dniu walenia głową.

Moje pytanie brzmi: jak mogę uzyskać podszywanie się pod aplikację, aby powrócić do użytkownika w pliku web.config? Lub, kiedy składasz moją prośbę, czy istnieje sposób na zapewnienie, że kontekst personifikacji dotyczy tylko tego żądania?

Najważniejsze jest to, że druga aplikacja ma własną bazę danych serwera sql. Podstawowa aplikacja używa DB2. Chciałbym raz wpisać kod dostępu do bazy danych, ale użyję go w obu aplikacjach. Obecnie to właśnie zrobiłem, ale moja metoda polegania na żądaniu strony internetowej, aby uzyskać dane, może nie być najlepszym podejściem.

Jestem otwarty na wszelkie przemyślenia, komentarze, sugestie i/lub krytykę. Jak mam sobie z tym poradzić?

+0

Czy jest coś, co muszę wyjaśnić? Czy sposób, w jaki powstaje pytanie, przeszkadza? Opinia została przyjęta z zadowoleniem. Nie mam nic przeciwko przeprojektowaniu lub wyjaśnieniu tam, gdzie to możliwe. – jason

Odpowiedz

1

Okay ... moja teoria, że ​​kontekst IPrincipala został zmieniony, gdy żądanie sieci okazało się poprawne, co bardzo uprościło tę poprawkę. Najlepsze jest to, że mogę nadal używać api, które zbudowałem, aby wykonać to żądanie bez duplikowania części Sql Server Entity Framework.

Mam następujące wezwanie do mojej biblioteki API:

  proxyRequestResultDetails = ProxyApiWrapper.GetProxies(
       adUserInfo.AssociateId, 
       context.User); 

Kod ten jest nazywany przez atrybut filtra autoryzacji. Prototyp metoda wygląda

public void OnAuthorization(AuthorizationContext filterContext)  

Wewnętrznie, rozmowa sprawia GetProxies metoda następujące połączenia:

 public static StreamReader GetWebRequestStream(
      string url, 
      string contentType, 
      bool useDefaultCredentials, 
      IPrincipal user) 
     { 

      var impersonationContext = ((WindowsIdentity)user.Identity).Impersonate();    
      var request = WebRequest.Create(url); 

      try 
      { 
       request.ContentType = contentType; 
       //request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; 
       //request.UseDefaultCredentials = useDefaultCredentials;    
       //IWebProxy p = new WebProxy(); 
       //request.Proxy = p. 
       request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested; 
       request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials; 
       var response = (HttpWebResponse)request.GetResponse(); 
       return new StreamReader(response.GetResponseStream()); 
      } 
      catch (Exception e) 
      { 
       impersonationContext.Undo(); 
       throw e; 
      } 
      finally 
      { 
       impersonationContext.Undo(); 
      } 

     } 

Kiedy powraca metoda powołanie, tożsamość użytkownika nie jest już, że z jednej ustawione dla aplikacja do podszywania się pod numer . Poprawka jest dość prosta:

  //Track current identity before proxy call 
      IPrincipal user = context.User; 
      proxyRequestResultDetails = ProxyApiWrapper.GetProxies(
       adUserInfo.AssociateId, 
       context.User); 

      //Undo any impersonating done in the GetProxies call 
      context.User = user;  

2 linie kodu rozwiązały 12 godzin bólu głowy. Mogło być gorzej. W każdym razie. Dzięki za bycie płytą dźwiękową. Próbowałem po tej konwersji z kaczką, ale kaczka się pomyliła.