我试图绕过https证书验证只到我们自己的测试环境(多台机器),同时试图保持所有其他连接的证书验证。
从在线阅读,大多数(如果不是全部)WCF相关的建议似乎指向类似的以下内容
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
但是,这是一个全局设置,我想仅将其应用于特定连接。这甚至是可能/支持的使用场景吗?
像这样的东西:
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(ValidateCert);
public static bool ValidateCert(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
string requestHost;
if(sender is string)
{
requestHost = sender.ToString();
}
else
{
HttpWebRequest request = sender as HttpWebRequest;
if(request != null)
{
requestHost = request.Host;
}
}
if(!string.IsNullOrEmpty(requestHost) && requestHost == "my_test_machine")
return true;
return sslPolicyErrors == SslPolicyErrors.None;
}
注意documentation参数上的sender
:
传递给RemoteCertificateValidationCallback的sender参数可以是主机字符串名称,也可以是从WebRequest(例如HttpWebRequest)派生的对象,具体取决于CertificatePolicy属性
免责声明 - 我没有测试这个,我是根据文档编写的。因人而异。
在使用.net 4.5时,我终于找到了真正的解决方案。
此代码允许您仅为特定WCF客户端使用自定义验证程序。
它已经使用BasicHttpSecurityMode.Transport
针对BasicHttpBinding进行了测试。
SslCertificateAuthentication
有一处名为ClientBase.ClientCredentials.ServiceCertificate
的新酒店。
您可以使用X509ServiceCertificateAuthentication
初始化此属性,您可以在其中提供自定义X509CertificateValidator
。
例如:
// initialize the ssl certificate authentication
client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = new X509ServiceCertificateAuthentication()
{
CertificateValidationMode = X509CertificateValidationMode.Custom,
CustomCertificateValidator = new CustomValidator(serverCert)
};
// simple custom validator, only valid against a specific thumbprint
class CustomValidator : X509CertificateValidator
{
private readonly X509Certificate2 knownCertificate;
public CustomValidator(X509Certificate2 knownCertificate)
{
this.knownCertificate = knownCertificate;
}
public override void Validate(X509Certificate2 certificate)
{
if (this.knownCertificate.Thumbprint != certificate.Thumbprint)
{
throw new SecurityTokenValidationException("Unknown certificate");
}
}
}
在.NET 4.5中似乎可以执行以下操作:
var request = (HttpWebRequest)WebRequest.Create(url);
request.ServerCertificateValidationCallback +=
(sender, certificate, chain, sslPolicyErrors) => true
我最初没有意识到,因为你实际上必须将qazxsw poi方法的结果投射到qazxsw poi,因为抽象的qazxsw poi不包含这个委托。
我想建议你采用更“犹太”的方式(从信息安全的角度来看):
Create
是您的开发人员机器的自签名唯一证书HttpWebRequest
此证书到您的测试服务实例上的“Trusted root”证书存储区这将允许您使用您的服务,而无需在代码中创建“后门”。这也允许您限制对测试环境的测试访问,同时在Test和Prod实例上具有相同的代码。
您可以做的是在您的web.config文件中放置一个设置。
然后在您的代码中检查web.config文件中的值。然后根据该值设置证书验证。
编辑
一种选择是:
Add
另一个是:var noCertValidationAuth = new X509ServiceCertificateAuthentication()
{
CertificateValidationMode = X509CertificateValidationMode.None
};
client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = noCertValidationAuth;
编辑2
尝试这样的事情:
answer
我在Web.config文件中使用了一个标志来指示证书何时是自签名的,并且我们也知道我们处于开发环境中:
String url = "https://www.stackoverflow.com";
HttpWebRequest request = HttpWebRequest.CreateHttp(url);
request.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
在代码中,我们必须检查此标志以应用证书验证异常:
http://weblog.west-wind.com/posts/2011/Feb/11/HttpWebRequest-and-Ignoring-SSL-Certificate-Errors