HttpWebRequest、TLS 和应用程序池服务标识
HttpWebRequest, TLS and application pool service identity
我们使用 HttpWebRequest
对远程服务器进行 Web 服务调用。该调用需要从本地计算机加载证书。
我们 运行 遇到的问题是,如果应用程序池标识设置为 NetworkService
,则调用失败并在 HttpWebResponse.GetResponse()
调用上出现一般 TLS/SSL 错误.如果我们将应用程序池用户的身份更改为 LocalSystem
,那么它将正常运行。
我想弄清楚的是为什么。 LocalSystem
可以访问哪些 NetworkService
不能访问的内容,这会影响 post 调用?
代码非常简单:
string URL = "https://mywebserver.net";
X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certResults = store.Certificates.Find(X509FindType.FindBySubjectName, "nameofthecertificate", false);
/* I have confirmed that the certificate is found regardless of
* how the application pool is configured.
*/
X509Certificate cert = certResults[0];
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);
req.AllowAutoRedirect = true;
req.ClientCertificates.Add(cert);
req.Method = "POST";
req.ContentType = "application/soap+xml;charset=UTF-8";
StringBuilder postData = new StringBuilder();
postData.Append("some soap info");
byte[] postBytes = Encoding.UTF8.GetBytes(postData.ToString());
using (Stream postStream = req.GetRequestStream())
{
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
}
// dies here when running under NetworkService
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
String data = String.Empty;
using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
{
data = reader.ReadToEnd();
reader.Close();
}
一般来说,一个Application Pool需要一个Identity来运行下。您可以像您一样将其身份配置为 运行,但请记住,不同的身份具有不同级别的权限。
您的问题可能很简单,就是应用程序池标识没有权限
使用它试图执行的代码。您可以通过查看部署的项目文件夹权限来检查。
既然你提到了 SSL/TLS 错误,我会认为该身份没有安装证书的权限。打开 mmc
并检查 Local Computer/Personal/Certificates
商店中是否有证书。如果这样做,请右键单击该证书并转到 All Tasks -> Manage Private Keys...
。通过从您的计算机位置添加应用程序池标识来添加它:
IIS AppPool\YourNameOfAppPool
.
你不应该再看到一个对话框说找不到它你添加正确。
阅读有关应用程序池标识的更多信息here。
我们使用 HttpWebRequest
对远程服务器进行 Web 服务调用。该调用需要从本地计算机加载证书。
我们 运行 遇到的问题是,如果应用程序池标识设置为 NetworkService
,则调用失败并在 HttpWebResponse.GetResponse()
调用上出现一般 TLS/SSL 错误.如果我们将应用程序池用户的身份更改为 LocalSystem
,那么它将正常运行。
我想弄清楚的是为什么。 LocalSystem
可以访问哪些 NetworkService
不能访问的内容,这会影响 post 调用?
代码非常简单:
string URL = "https://mywebserver.net";
X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
var certResults = store.Certificates.Find(X509FindType.FindBySubjectName, "nameofthecertificate", false);
/* I have confirmed that the certificate is found regardless of
* how the application pool is configured.
*/
X509Certificate cert = certResults[0];
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);
req.AllowAutoRedirect = true;
req.ClientCertificates.Add(cert);
req.Method = "POST";
req.ContentType = "application/soap+xml;charset=UTF-8";
StringBuilder postData = new StringBuilder();
postData.Append("some soap info");
byte[] postBytes = Encoding.UTF8.GetBytes(postData.ToString());
using (Stream postStream = req.GetRequestStream())
{
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Flush();
postStream.Close();
}
// dies here when running under NetworkService
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
String data = String.Empty;
using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
{
data = reader.ReadToEnd();
reader.Close();
}
一般来说,一个Application Pool需要一个Identity来运行下。您可以像您一样将其身份配置为 运行,但请记住,不同的身份具有不同级别的权限。
您的问题可能很简单,就是应用程序池标识没有权限 使用它试图执行的代码。您可以通过查看部署的项目文件夹权限来检查。
既然你提到了 SSL/TLS 错误,我会认为该身份没有安装证书的权限。打开 mmc
并检查 Local Computer/Personal/Certificates
商店中是否有证书。如果这样做,请右键单击该证书并转到 All Tasks -> Manage Private Keys...
。通过从您的计算机位置添加应用程序池标识来添加它:
IIS AppPool\YourNameOfAppPool
.
你不应该再看到一个对话框说找不到它你添加正确。
阅读有关应用程序池标识的更多信息here。