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

WCF服务-证书未到达服务器,wcf,ssl,ssl-certificate,x509certificate,Wcf,Ssl,Ssl Certificate,X509certificate,我有一个WCF服务,我想用它连接到外部提供者的API。我的服务中的客户端构造函数如下所示: public partial class SomePortTypeClient : System.ServiceModel.ClientBase<SomeService.ClientPortType>, SomeService.SomePortType { static partial void ConfigureEndpoint(System.ServiceModel

我有一个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");
        }
我已经与服务提供商联系过,他们可以告诉我,我的请求正在到达他们的服务器,但没有附加任何证书。因此,我的问题是,当我在客户端构造函数中按照以下行明确设置证书时,如何不附加证书:
this.ChannelFactory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine、System.Security.Cryptography.X509Certificates.StoreName.Root、System.Security.Cryptography.X509Certificates.X509FindType.FindBythythumbprint,“11AU2I3HIR3O1748905”);

证书链一切正常,没有任何证书过期或诸如此类的问题。这不是因为它们有任何问题,而是根本没有证书到达服务器。是否有其他方法将证书附加到我发送的请求

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

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.X509FindType.FindByThumbprint,“11AU2I3HIR3O1748905”);

2:
WebRequestHandler=newwebrequesthandler();

handler.ClientCertificates.Add(certificateCollection[0]);

使用证书对客户端进行身份验证需要双向信任关系,也就是说,我们必须信任服务器证书,并使我们提供的客户端证书受服务器信任。根据证书颁发方法,我们需要在客户端上安装服务器的根证书,以建立信任链信任或安装颁发给服务器的证书以建立对等信任。此外,为了确保WCF程序可以使用证书的私钥,我们通常会将
所有人
帐户添加到证书私钥管理组。
有关详细信息,请参阅以下文档。

此外,如果您不熟悉服务器的配置,请尝试通过添加服务引用来调用该服务,这将在本地生成正确的客户端代理和配置文件。
我想知道您的客户端证书是如何颁发的,以及您如何将其提供给服务器以使服务器信任您的证书。

如果有什么我可以帮忙的,请随时告诉我。

使用证书对客户端进行身份验证需要双向信任关系,也就是说,我们必须信任服务器证书,并使服务器信任我们提供的客户端证书。根据证书颁发方法,我们需要安装服务器的客户端上的根证书以建立信任链,或安装颁发给服务器的证书以建立对等信任。此外,为了确保WCF程序可以使用证书的私钥,我们通常将
每个人
帐户添加到证书私钥管理组。
有关详细信息,请参阅以下文档。

此外,如果您不熟悉服务器的配置,请尝试通过添加服务引用来调用该服务,这将在本地生成正确的客户端代理和配置文件。
我想知道您的客户端证书是如何颁发的,以及您如何将其提供给服务器以使服务器信任您的证书。

如果有什么我可以帮忙的,请随时告诉我。

更新的原始姿势更新的原始帖子您是否尝试过删除用户名/密码凭据,在HTTP请求标头中手动添加基本身份验证标头(我们可以使用weboperationcontext)?如果我们指定
clientcredentialtype
为证书,则可能会忽略基本标头,从而导致后面的问题。您是否尝试过删除用户名/密码凭据,在HTTP请求标头中手动添加基本身份验证标头(我们可以使用weboperationcontext)?如果我们指定
clientcredentialtype
is-certificate,则可能会忽略基本标头,从而导致后面的问题。
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();
        }