Make API call with Basic Auth using App Pool Credentials

1.1k views Asked by At

I am wondering if in .NET, if it possible to send over the credentials of the identity running an application pool in IIS to an API that uses Basic Auth. I have successfully been able to retrieve the identity context from the application pool. However, in every example i see for using Basic Auth. They all seem to require to manually add the Authorization header to the request. This is a problem since i do not directly have access to the password of the windows identity thus i can't manually create the Basic Auth Token. I have been trying to use the .DefaultCredentials property but it fails to generate the Auth header thus the response fails with 401. If this isn't possible then i'll take a different approach but wanted to make sure before i do so. The full code sample is below...i have tried multiple ways but all end up with the same 401.

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

There are 1 answers

1
dotNetAuthor On

App Pool Identity and Basic Auth serves two different purpose and I suggest not to mix those. As you also mentioned that you don't know the password of app pool identity and it's self explanatory. App pool identity also allows the API's to access system resources for example, accessing a file share.

Whereas Basic Auth allows you to secure your API as a whole from being wide open and anyone accessing it. Except the ones who knows UserName:Password which needs to be passed with each HttpRequest (containing HttpHeader with UserName:Password in Base64).

Considering these facts, when API developer needs to share UserName and Password with all the parties, it's advisable not to share App Pool Identity credentials.

I have worked with both App Pool Identity and Basic Auth and I recommend to keep these separate.