2013-02-01 9 views
5

Ho 2 applicazioni ASP.NET MVC 3. Sto usando la rappresentazione tramite web.config per permettermi di interrogare Active Directory per ottenere i dettagli sull'utente. L'applicazione utilizza l'autenticazione di Windows e non consente agli utenti anonimi. Un'applicazione è l'applicazione principale in cui l'utente esegue le proprie attività. L'altro consente all'utente di impostare altri utenti per assomigliare a loro nell'applicazione uno.Problemi di rappresentazione, Active Directory e "l'utente non ha autorità per xxxx"

L'utente di prova del stanno ottenendo il seguente errore:

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

Questo accade dopo che trasmetto una richiesta Web dalla mia applicazione primaria a quella secondaria. Per farlo funzionare ho dovuto fare in modo che la richiesta impersonasse l'utente reale e non l'identità utilizzata dall'applicazione per la rappresentazione. Questa è in realtà una domanda SO che ho postato e ha risposto. Ecco qui: How do I call an MVC Action via a WebRequest and validate the request through Active Directory?

Alla fine di quel codice, che io chiamo:

impersonationContext.Undo(); 

E 'dopo questa richiesta web avviene, che l'applicazione principale tenta l'accesso al database e ora sembra che la chiamata sopra ha annullato la rappresentazione dell'applicazione, quindi il tentativo dell'utente di eseguire qualsiasi operazione che apre una connessione al database non riesce. Almeno, questa è la mia teoria del lavoro dopo un giorno di pestaggio della testa.

La mia domanda è, come posso ottenere la rappresentazione dell'applicazione per tornare all'utente nel web.config? Oppure, quando si effettua la mia richiesta web, esiste un modo per garantire che il contesto di rappresentazione si applichi solo a tale richiesta?

L'intero punto di tutto questo è che la seconda applicazione ha il proprio database SQL Server. L'applicazione principale utilizza DB2. Vorrei scrivere una volta il codice di accesso al database, ma usarlo in entrambe le applicazioni. Attualmente è quello che ho fatto, ma il mio metodo di fare affidamento sulla richiesta web per ottenere i dati potrebbe non essere l'approccio migliore.

Sono aperto a qualsiasi pensiero, commento, suggerimento e/o critica. Come dovrei andare a gestire questo?

+0

C'è qualcosa che devo chiarire? Il modo in cui è formulata la domanda è d'intralcio? Feedback accolto Non mi dispiace riformulare o chiarire dove possibile. – jason

risposta

1

Okay ... la mia teoria che il contesto IPrincipal è stato modificato quando la richiesta Web si è dimostrata accurata, il che ha reso questa correzione estremamente facile. La parte migliore è che posso continuare a utilizzare l'API creata per eseguire questa richiesta senza duplicare le parti di Sql Server Entity Framework.

ho il seguente invito alla mia libreria API:

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

Questo codice viene chiamato da un attributo del filtro di autorizzazione. Il metodo prototipo si presenta come

public void OnAuthorization(AuthorizationContext filterContext)  

Internamente, la chiamata fa la GetProxies metodo seguente chiamata:

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

     } 

Quando il metodo di chiamata restituisce, l'identità di utente non è più quella di un set per la applicazione a impersonare. La soluzione è piuttosto semplice:

  //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 righe di codice risolte 12 ore di mal di testa. Sarebbe potuta andare peggio. Comunque. Grazie per essere una cassa di risonanza. Ho provato avendo questa conversione con l'anatra, ma l'anatra è stata confusa.