我正在尝试将https证书验证仅绕过我们自己的测试环境(多台计算机),同时尝试为所有其他连接保留证书验证。
通过在线阅读,大多数(如果不是全部)与WCF相关的建议似乎都指向类似以下的内容
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
但是,这是一个全局设置,我想仅将其应用于特定连接。这甚至是可能/支持的使用场景吗?
答案 0 :(得分:9)
使用.net 4.5时,我终于找到了真正的解决方案。
此代码允许您仅为特定WCF客户端使用自定义验证程序。
已使用BasicHttpSecurityMode.Transport
对BasicHttpBinding进行了测试。
ClientBase.ClientCredentials.ServiceCertificate
中有一个名为SslCertificateAuthentication
的新媒体资源。
您可以使用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");
}
}
}
答案 1 :(得分:3)
似乎在.NET 4.5中,您可以执行以下操作:
var request = (HttpWebRequest)WebRequest.Create(url);
request.ServerCertificateValidationCallback +=
(sender, certificate, chain, sslPolicyErrors) => true
我最初没有意识到这一点,因为您实际上必须将Create
方法的结果转换为HttpWebRequest
,因为抽象WebRequest
不包含此委托。
答案 2 :(得分:2)
这样的事情:
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;
}
请注意sender
参数上的documentation:
传递给RemoteCertificateValidationCallback的sender参数可以是主机字符串名称,也可以是从WebRequest派生的对象(例如,HttpWebRequest),具体取决于CertificatePolicy属性
免责声明 - 我没有对此进行测试,我是根据文档编写的。 YMMV。
答案 3 :(得分:1)
我想建议你采用更“犹太”的方式(从信息安全的角度来看):
答案 4 :(得分:1)
您实际上可以使用以下代码禁用每个客户端/渠道的SSL证书验证:
var noCertValidationAuth = new X509ServiceCertificateAuthentication()
{
CertificateValidationMode = X509CertificateValidationMode.None
};
client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication = noCertValidationAuth;
这个帖子实际上是answer的变体,所以在那里赞不绝口。
答案 5 :(得分:0)
您可以做的是在您的web.config文件中放置一个设置。
然后在您的代码中检查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
修改2
尝试这样的事情:
ServicePointManager.ServerCertificateValidationCallback += customXertificateValidation;
private static bool customXertificateValidation(object sender, X509Certificate cert,
X509Chain chain, SslPolicyErrors error)
{
if (check something here)
{
return true;
}
return false;
}
答案 6 :(得分:0)
我在Web.config文件中使用了一个标志来指示证书何时自签名 我们也知道我们处于开发环境中:
<add key="isSelfSignedCertificate" value="true"/>
在代码中,我们必须检查此标志以应用证书验证例外:
using System.Net;
bool isSelfSignedCertificate = Convert.ToBoolean(ConfigurationManager.AppSettings["isSelfSignedCertificate"]);
if (isSelfSignedCertificate)
{
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
}