WCF服务-证书未到达服务器
我有一个WCF服务,我想用它连接到外部提供者的API。我的服务中的客户端构造函数如下所示: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
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();
}