2017-05-01 1 views
0

Ich frage mich, ob in .NET, wenn es möglich ist, über die Anmeldeinformationen der Identität einen Anwendungspool in IIS zu einer API, die Basic Auth verwendet. Ich konnte den Identitätskontext erfolgreich aus dem Anwendungspool abrufen. In jedem Beispiel sehe ich für die Verwendung von Basic Auth. Sie alle scheinen es erforderlich, den Autorisierungsheader der Anforderung manuell hinzuzufügen. Dies ist ein Problem, da ich nicht direkt Zugriff auf das Passwort der Windows-Identität habe, so dass ich das Basic Auth Token nicht manuell erstellen kann. Ich habe versucht, die .DefaultCredentials Eigenschaft zu verwenden, aber es erzeugt den Authheader nicht, folglich schlägt die Antwort mit 401 fehl. Wenn dies nicht möglich ist, werde ich einen anderen Ansatz nehmen, aber sicher sein wollte, bevor ich dies tue. Das vollständige Codebeispiel ist unten ... Ich habe mehr Möglichkeiten ausprobiert, aber alle am Ende mit den gleichen 401.Make API-Aufruf mit Basic Auth mit App Pool Credentials

  using (var impersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero)) 
     { 
      HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("url"); 
      HttpClient request2 = new HttpClient(); 
      WebClient request3 = new WebClient(); 
      WebRequest request4 = WebRequest.Create("url"); 

      try 
      { 
       // this code is now using the application pool indentity 
       try 
       { 
        //Method 1 
        //request1.UseDefaultCredentials = true; 
        //request1.PreAuthenticate = true; 
        //string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(WindowsIdentity.GetCurrent().Name + ":" + "No password :(")); 
        //request1.Headers.Add("Authorization", "Basic " + WindowsIdentity.GetCurrent().Token.ToString()); 
        //HttpWebResponse response = (HttpWebResponse)request1.GetResponse(); 
        //using (var reader = new StreamReader(response.GetResponseStream())) 
        //{ 
        // JavaScriptSerializer js = new JavaScriptSerializer(); 
        // var objText = reader.ReadToEnd(); 
        // Debug.WriteLine(objText.ToString()); 
        //} 

        ////Method 2 
        //client.DefaultRequestHeaders.Accept.Clear(); 
        //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
        //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", WindowsIdentity.GetCurrent().Token.ToString()); 
        //HttpResponseMessage response2 = client.GetAsync("url").Result; //.Result forces sync instead of async. 
        //var result = response2.Content.ReadAsStringAsync().Result; 
        //Debug.WriteLine(result); 

        //Method 3 
        //client2.Credentials = CredentialCache.DefaultNetworkCredentials; 
        //var result2 = client2.DownloadString("url"); 
        //Debug.WriteLine(result2); 

        //Method 4 
        //request4.Credentials = CredentialCache.DefaultCredentials; 
        //string result4; 
        //using (var sr = new StreamReader(request4.GetResponse().GetResponseStream())) 
        //{ 
        // result4 = sr.ReadToEnd(); 
        //} 
        //Debug.WriteLine(result4); 
       } 
       catch (Exception ex) 
       { 
        throw new Exception("API Call Failed: " + ex.ToString() + " for " + WindowsIdentity.GetCurrent().Name + " request: " + request4.Headers.ToString()); 
       } 
      } 
      finally 
      { 
       if (impersonationContext != null) 
       { 
        impersonationContext.Undo(); 
       } 
      } 
+0

Dies scheint eine Menge von Informationen zu haben, die wie das klingt, was Sie wollen http://stackoverflow.com/questions/12212116/how-to-get-httpclient-to-pass-credentials-along-with-the -request –

+0

Nach der Aktualisierung des Codes zu ihrem Anwendungsfall, erhielt es immer noch eine 401. Ich inspizierte die Header für die Anfrage und der Autorisierungsheader wurde immer noch weggelassen, weshalb es fehlschlägt. – user1732364

+0

Sind Sie auf Basic Auth beschränkt? Vielleicht funktioniert NTLM so lange, wie sich die API-Aufrufe im selben Thread befanden, in dem die Anwendung ausgeführt wurde (httpclient vs webclient)? –

Antwort

0

App Pool Identität und Basic Auth dienen zwei unterschiedliche Zwecken und ich schlage vor, nicht diejenigen zu mischen. Wie du bereits erwähnt hast, kennst du das Passwort der App-Pool-Identität nicht und es ist selbsterklärend. Die App-Pool-Identität ermöglicht den APIs auch den Zugriff auf Systemressourcen, z. B. Zugriff auf eine Dateifreigabe.

Während Basic Auth Ihnen erlaubt, Ihre API als Ganzes davon zu schützen, weit geöffnet zu sein und jeder, der darauf zugreift. Außer denen, die UserName kennen: Passwort, das mit jedem HttpRequest (mit HttpHeader mit UserName: Passwort in Base64) übergeben werden muss.

In Anbetracht dieser Tatsachen ist es ratsam, wenn der API-Entwickler UserName und Password mit allen Teilnehmern teilen muss, die App Pool Identity-Anmeldeinformationen nicht zu teilen.

Ich habe mit App Pool Identity und Basic Auth gearbeitet und ich empfehle, diese getrennt zu halten.

+0

Korrekt. Wir verwenden hauptsächlich Dienstkonten, die den Zugriff auf Systeme usw. steuern. Wir möchten diesen Anwendungsfall einfach auf den API-Zugriff erweitern. Um dies streamlos zu tun, könnte eine .NET-Anwendung die Anmeldeinformationen des Dienstkontos wiederverwenden, um auf ihre Ressourcen zuzugreifen. Dies würde nicht das Speichern von Anmeldeinformationen oder eines Schlüsselspeichers erfordern. Die Wand, die ich treffe, ist einfach die Hinzufügung des Authorization-Headers für die Anfrage zusammen mit dem Basisauth-Token. – user1732364