WCF 服务 - 证书未到达服务器

标签 wcf ssl ssl-certificate x509certificate

我有一个 WCF 服务,我想用它来连接到外部提供商的 API。我服务中的客户端构造函数如下所示:

public partial class SomePortTypeClient : System.ServiceModel.ClientBase<SomeService.ClientPortType>, SomeService.SomePortType
    {
        static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);

        public SomePortTypeClient(string endpointUrl, string username, string password) :
        base(SomePortTypeClient.GetBindingForEndpoint(), SomePortTypeClient.GetEndpointAddress(endpointUrl))
        {
            this.ChannelFactory.Credentials.UserName.UserName = username;
            this.ChannelFactory.Credentials.UserName.Password = password;          
            this.ChannelFactory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, 
                System.Security.Cryptography.X509Certificates.StoreName.Root, System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "11au2i3h3ir3o1748905");
        }

我有服务提供商提供的三份证书,一份是普通证书,一份是中级证书,一份是根证书。这三个都安装在我本地计算机上的个人和受信任的根文件夹中。

然后是客户端的实际实现和调用端点:

SomePortTypeClient someClient = new SomePortTypeClient("https://endpointURL", "username", "password");

var response = someClient.someMethod(someParameter).Result;

我已与服务提供商联系,他们可以告诉我我的请求已到达他们的服务器,但没有附加任何证书。所以我的问题是,当我按照以下行在客户端构造函数中明确设置证书时,如何不附加证书:this.ChannelFactory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.Root, System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "11au2i3h3ir3o1748905");

证书链一切正常,没有证书过期或类似情况。并不是他们有什么问题,而是根本没有证书到达服务器。是否有其他方法可以将证书附加到我发送的请求中?

编辑:我尝试使用以下代码以另一种方式调用服务:

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, "13865db1e2cfbed62966c8098bb33384b053e4b5", true);

WebRequestHandler handler = new WebRequestHandler();
handler.ClientCertificates.Add(certificateCollection[0]);

var httpClient = new HttpClient(handler);
var yourusername = "user";
var yourpwd = "pwd";

var request = new HttpRequestMessage(){
                RequestUri = new Uri(@"URI"),
                Method = HttpMethod.Post
            };

request.Content = new StringContent(soapRequest.ToString(), Encoding.UTF8, "text/xml");
request.Headers.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
request.Content.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes($"{yourusername}:{yourpwd}")));
request.Headers.Add("SOAPAction", "URI");

HttpResponseMessage response = httpClient.SendAsync(request).Result;
            response.Content.ReadAsStringAsync().Result.Split('>').ToList().ForEach(x=> Console.WriteLine(x));
Console.ReadLine();
        }

这有效!所以很明显,证书或信任链或类似的东西没有任何问题。但是为什么用第二种方法将证书附加到请求中,而不是第一种方法呢?只是为了澄清添加证书的两种不同方法:

1:this.ChannelFactory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.Root, System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "11au2i3h3ir3o1748905");

2:WebRequestHandler handler = new WebRequestHandler(); handler.ClientCertificates.Add(certificateCollection[0]);

最佳答案

使用证书对客户端进行身份验证需要双向信任关系,即我们既要信任服务器证书,又要使我们提供的客户端证书得到服务器的信任。根据证书颁发方式,我们需要在客户端安装服务器的根证书建立信任链或者安装颁发给服务器的证书建立对等信任。另外,为了保证WCF程序可以使用证书的私钥,我们通常会在证书私钥管理组中添加Everyone账号。
详情请引用以下文档。
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/working-with-certificates
另外,如果您不熟悉服务器的配置,请尝试通过添加服务引用来调用服务,这将在本地生成正确的客户端代理和配置文件。
我想知道你客户端的证书是怎么颁发的,你是怎么提供给服务器让服务器信任你的证书的。
如果有什么我可以帮忙的,请随时告诉我。

关于WCF 服务 - 证书未到达服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59072579/

相关文章:

ssl - 如果将 http 重定向到 https nginx,我们是否需要在第二个服务器 block 中使用 server_name

wcf - 无法让 WCFExtras 与 WCF 服务配合使用

WCF:客户端上的集合代理类型

c# - JSON解析日期时间

ssl - nginx proxy_pass SSL 不工作

perl - 如何忽略 perl 中的 'Certificate Verify Failed' 错误?

Azure 应用服务和 SSL 证书

c# - WCF 中的动态对象不可能吗?

ssl - 是否可以根据服务器的公钥验证保存的 SSL session

Python SSL X509 : KEY_VALUES_MISMATCH