2013-02-01 5 views
5

Ich habe 2 ASP.NET MVC 3-Anwendungen. Ich verwende den Identitätswechsel über die Datei "web.config", damit ich Active Directory abfragen kann, um Details zum Benutzer zu erhalten. Die Anwendung verwendet die Windows-Authentifizierung und lässt keine anonymen Benutzer zu. Eine Anwendung ist die primäre Anwendung, in der der Benutzer seine Aufgaben ausführt. Mit der anderen Option kann der Benutzer andere Benutzer so einrichten, dass sie in der ersten Anwendung wie diese aussehen.Identitätswechsel, Active Directory, und "Benutzer keine Berechtigung auf xxxx" gibt

Der Test des Benutzer werden die folgenden Fehler bekommen:

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

Dies geschieht, nachdem ich eine Web-Anfrage von meiner primären Anwendung auf den sekundären senden. Um das zu erreichen, musste ich die Anfrage als den tatsächlichen Benutzer und nicht die Identität, die die Anwendung für den Identitätswechsel verwendet, imitieren. Das ist eigentlich eine SO-Frage, die ich gestellt und beantwortet habe. Das ist hier: How do I call an MVC Action via a WebRequest and validate the request through Active Directory?

Am Ende dieses Codes, ich rufe:

impersonationContext.Undo(); 

Es ist nach dieser Web-Anfrage stattfindet, dass die primäre Anwendung versucht, Zugriff auf die Datenbank und jetzt scheint es, dass der oben genannten Aufruf hat den Identitätswechsel der Anwendung rückgängig gemacht, so dass der Versuch des Benutzers, alles zu tun, was eine Datenbankverbindung öffnet, fehlschlägt. Zumindest ist das meine Arbeitstheorie nach einem Tag des Kopfschlagens.

Meine Frage ist, wie kann ich die Personifizierung der Anmeldung erhalten in der web.config für den Benutzer wieder zurück? Oder gibt es bei meiner Webanfrage eine Möglichkeit, sicherzustellen, dass der Identitätswechselkontext nur für diese Anfrage gilt?

Der ganze Sinn von all dem ist, dass die zweite Anwendung eine eigene SQL-Server-Datenbank verfügt. Die primäre Anwendung verwendet DB2. Ich möchte den Datenbankzugriffscode einmal schreiben, aber in beiden Anwendungen verwenden. Momentan habe ich das gemacht, aber meine Methode, sich auf die Webanfrage zu verlassen, um die Daten zu bekommen, ist vielleicht nicht der beste Ansatz.

Ich bin offen für jeden Gedanken, Kommentare, Anregungen und/oder Kritik. Wie soll ich damit umgehen?

+0

Gibt es etwas, das ich klären muss? Ist die Art, wie die Frage formuliert wird, in die Quere gekommen? Feedback begrüßt. Es macht mir nichts aus, wenn ich es anders formuliere oder klärere. – jason

Antwort

1

Okay ... meine Theorie, dass der IPrincipal Kontext verändert wurde, als was die Web-Anfrage genau erwiesen, die diese extrem einfach beheben gemacht. Der beste Teil ist, kann ich weiterhin die API, die ich gebaut habe, um diese Anfrage zu machen, ohne die Sql Server Entity Framework Teile zu duplizieren.

Ich habe den folgenden Aufruf an meine api Bibliothek:

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

Dieser Code durch ein Berechtigungs Filter Attribut aufgerufen wird. Die Methode Prototyp sieht aus wie

public void OnAuthorization(AuthorizationContext filterContext)  

Intern macht der Aufruf der GetProxies Methode folgenden Aufruf:

 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(); 
      } 

     } 

Wenn die rufende Methode zurückgibt, die Identität des Benutzers nicht mehr ist, dass von dem einen Satz für die Anwendung auf imitieren. Die Lösung ist ziemlich einfach:

  //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 Zeilen Code aufgelöst 12 Stunden Kopfschmerz. Es könnte schlimmer sein. Jedenfalls. Danke, dass du ein Resonanzboden bist. Ich versuchte mit dieser Umwandlung mit der Ente, aber die Ente wurde verwirrt.

Verwandte Themen