繁体   English   中英

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

[英]WCF service - Certificate not reaching server

我有一个 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");我的客户端构造函数中明确设置证书时,如何不附加证书: 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]); 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
另外,如果您不熟悉服务器的配置,请尝试通过添加服务引用来调用服务,这将在本地生成正确的客户端代理和配置文件。
我想知道你客户端的证书是怎么颁发的,你是怎么提供给服务器的,让服务器信任你的证书。
如果有什么我可以帮忙的,请随时告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM