C# 使用应用程序池凭据使用基本身份验证进行API调用

C# 使用应用程序池凭据使用基本身份验证进行API调用,c#,basic-authentication,api-auth,C#,Basic Authentication,Api Auth,我想知道在.NET中,是否可以将IIS中运行应用程序池的身份的凭据发送到使用基本身份验证的API。我已成功地从应用程序池中检索到标识上下文。然而,在我看到的每个使用basicauth的示例中。它们似乎都需要手动将授权头添加到请求中。这是一个问题,因为我无法直接访问windows标识的密码,因此无法手动创建基本身份验证令牌。我一直在尝试使用.DefaultCredentials属性,但它无法生成Auth头,因此401响应失败。如果这是不可能的,那么我将采取另一种方法,但我希望在这样做之前确保。下面

我想知道在.NET中,是否可以将IIS中运行应用程序池的身份的凭据发送到使用基本身份验证的API。我已成功地从应用程序池中检索到标识上下文。然而,在我看到的每个使用basicauth的示例中。它们似乎都需要手动将授权头添加到请求中。这是一个问题,因为我无法直接访问windows标识的密码,因此无法手动创建基本身份验证令牌。我一直在尝试使用.DefaultCredentials属性,但它无法生成Auth头,因此401响应失败。如果这是不可能的,那么我将采取另一种方法,但我希望在这样做之前确保。下面是完整的代码示例…我尝试了多种方法,但最终都得到了相同的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();
                }
            }

应用程序池标识和基本身份验证有两个不同的用途,我建议不要混用它们。正如您还提到的,您不知道应用程序池标识的密码,这是不言自明的。应用程序池标识还允许API访问系统资源,例如访问文件共享

而basicauth允许您保护您的API作为一个整体,使其不被完全开放和任何人访问。除了那些知道UserName:Password的人,每个HttpRequest都需要传递这个密码(在Base64中包含UserName:Password的HttpHeader)

考虑到这些事实,当API开发人员需要与各方共享用户名和密码时,建议不要共享应用程序池身份凭据


我已经使用了应用程序池标识和基本身份验证,我建议将它们分开。

这似乎有很多信息,听起来像是你想要的。在将代码更新到它们的用例后,它仍然收到了401。我检查了请求的头,授权头仍然被忽略,这就是它失败的原因。您是否仅限于基本身份验证?也许只要API调用在应用程序运行的同一线程中(httpclient vs webclient),NTLM就可以工作?正确。我们主要使用控制系统访问等的服务帐户。我们只是想将此用例扩展到API访问。要以无流方式执行此操作,.NET应用程序可以重用服务帐户凭据来访问其资源。这不需要存储凭据或密钥库。我遇到的障碍只是为请求添加了授权头和基本的auth令牌。