gpt4 book ai didi

c# - 以证书作为 ClientCredentials 的 Wcf

转载 作者:行者123 更新时间:2023-11-30 12:27:19 24 4
gpt4 key购买 nike

在我使用相互证书验证客户端的 WCF 自托管 WebService 中,我设置了 CertificateValidationMode = PeerTrust 但它似乎被忽略了,因为我仍然可以使用我已删除的某些客户端执行这些方法TrustedPeople 服务器存储的相应证书。

这是主机示例:

  static void Main()
{
var httpsUri = new Uri("https://192.168.0.57:xxx/HelloServer");
var binding = new WSHttpBinding
{
Security =
{
Mode = SecurityMode.Transport,
Transport = {ClientCredentialType = HttpClientCredentialType.Certificate}
};

var host = new ServiceHost(typeof(HelloWorld), httpsUri);

//This line is not working
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode =X509CertificateValidationMode.PeerTrust;

host.AddServiceEndpoint(typeof(IHelloWorld), binding, string.Empty, httpsUri);

host.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
"server.com");

// Open the service.
host.Open();
Console.WriteLine("Listening on {0}...", httpsUri);
Console.ReadLine();

// Close the service.
host.Close();
}

客户端应用:

 static void Main(string[] args)
{
try
{
var c = new HelloWorld.HelloWorldClient();
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, error) => true;
c.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
"client.com");

Console.WriteLine(c.GetIp());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}

我使用 RootCA 证书生成 server.comclient.com。此 RootCA 证书安装在客户端和服务器的受信任根存储上。问题是,如果我的 client.com 证书不在服务器的 TrustedPeople 存储中,我不应该执行 GetIp() 方法,正确的?但是我执行它没有任何问题。

问题是,在这种情况下,如何验证客户端证书将其公钥放在服务器的 TrustedPeople 上?

附:在this MSDN Transport security with client certificate 的文章中有一句话说 服务器的证书必须被客户端信任,客户端的证书必须被服务器信任。 但是我可以从客户端执行 web 方法,即使客户端证书不在服务器 TrustedPeople 存储中。

最佳答案

我的建议是使用 custom validation .通过这种方式,您可以设置一些断点并观察验证的进行,并查看您可以根据整个验证过程中可用的数据提出哪些其他验证选项。

首先确保您的绑定(bind)需要 消息 客户端凭据的证书。如果您仅使用证书进行传输,则我测试中的客户端未验证。仅此一项就可以解决您的问题。

binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Message.ClientCredentialType =
MessageCredentialType.Certificate;

要设置自定义验证器,请遵循其余部分。

替换:

host.Credentials.ClientCertificate.Authentication.CertificateValidationMode 
=X509CertificateValidationMode.PeerTrust;

与:

host.Credentials.ClientCertificate.Authentication.CertificateValidationMode 
=X509CertificateValidationMode.Custom;

host.Credentials.ClientCertificate.Authentication.CustomCertificateValidator =
new IssuerNameCertValidator("CN=client.com");

然后添加此代码以创建自定义验证器并根据需要进行调整(此验证器基于 Issuer):

public class IssuerNameCertValidator : X509CertificateValidator
{
string allowedIssuerName;

public IssuerNameCertValidator(string allowedIssuerName)
{
if (allowedIssuerName == null)
{
throw new ArgumentNullException("allowedIssuerName");
}

this.allowedIssuerName = allowedIssuerName;
}

public override void Validate(X509Certificate2 certificate)
{
// Check that there is a certificate.
if (certificate == null)
{
throw new ArgumentNullException("certificate");
}

// Check that the certificate issuer matches the configured issuer.
if (allowedIssuerName != certificate.IssuerName.Name)
{
throw new SecurityTokenValidationException
("Certificate was not issued by a trusted issuer");
}
}
}

关于c# - 以证书作为 ClientCredentials 的 Wcf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25667501/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com