我们有一个使用证书保护的 ODATA 服务。我们正在使用 AddWebReference 在我们的 C# 代码中获取代理。
有没有办法将我们证书存储中的证书附加到这个生成的代理类?
我们可以使用 来添加证书HTTPClient
,但我们希望避免使用HTTPClient
来与我们的 ODATA 服务通信,而是更喜欢使用 AddWebReference 方法。
我们有一个使用证书保护的 ODATA 服务。我们正在使用 AddWebReference 在我们的 C# 代码中获取代理。
有没有办法将我们证书存储中的证书附加到这个生成的代理类?
我们可以使用 来添加证书HTTPClient
,但我们希望避免使用HTTPClient
来与我们的 ODATA 服务通信,而是更喜欢使用 AddWebReference 方法。
我想这对您来说可能为时已晚 3 年,但希望其他人会得到帮助。
这篇文章实际上非常详细地解释了需要什么。
您需要将ClientCertificate
属性添加到通过添加 Web 引用生成的容器中并使用它。您可以通过创建一个添加行为的部分类来做到这一点:
public partial class YourContainer
{
private X509Certificate clientCertificate = null;
public X509Certificate ClientCertificate
{
get
{
return clientCertificate;
}
set
{
if (value == null)
{
// if the event has been hooked up before, we should remove it
if (clientCertificate != null)
this.SendingRequest -= this.OnSendingRequest_AddCertificate;
}
else
{
// hook up the event if its being set to something non-null
if (clientCertificate == null)
this.SendingRequest += this.OnSendingRequest_AddCertificate;
}
clientCertificate = value;
}
}
private void OnSendingRequest_AddCertificate(object sender, SendingRequestEventArgs args)
{
if (null != ClientCertificate)
{
((HttpWebRequest)args.Request).ClientCertificates.Add(ClientCertificate);
}
}
}
在实例化的容器上,您现在可以ClientCertificate
使用所需的证书设置属性:
// Get the store where your certificate is in.
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
// Select your certificate from the store (any way you like).
X509Certificate2Collection certColl = store.Certificates.Find(X509FindType.FindByThumbprint, yourThumbprint, false);
// Set the certificate property on the container.
container.ClientCertificate = certColl[0];
store.Close();
现在,如果您使用的是 WCF Dataservice 5+,则 SendingRequest 事件已被弃用,如属性所示[Obsolete("SendingRequest2 has been deprecated in favor of SendingRequest2.")]
(不是我这边的错字;))。我认为你仍然可以使用它,但是,如果你想使用 SendingRequest2,你的部分应该如下所示:
public partial class YourContainer
{
private X509Certificate clientCertificate = null;
public X509Certificate ClientCertificate
{
get
{
return clientCertificate;
}
set
{
if (value == null)
{
// if the event has been hooked up before, we should remove it
if (clientCertificate != null)
this.SendingRequest2 -= this.OnSendingRequest_AddCertificate;
}
else
{
// hook up the event if its being set to something non-null
if (clientCertificate == null)
this.SendingRequest2 += this.OnSendingRequest_AddCertificate;
}
clientCertificate = value;
}
}
private void OnSendingRequest_AddCertificate(object sender, SendingRequest2EventArgs args)
{
if (null != ClientCertificate)
{
((HttpWebRequestMessage)args.RequestMessage).HttpWebRequest.ClientCertificates.Add(ClientCertificate);
}
}
}
这对我来说适用于非批量请求(通过反复试验发现,因为我找不到很多关于 和 之间差异的文档SendingRequest
)SendingRequest2
。
但是,我现在似乎遇到了一些麻烦,因为我args.RequestMessage
是 type 而不是HttpWebRequestMessage
导致InvalidCastExceptions
. 这实际上是我最终提出这个问题的原因。似乎只有批处理操作才会出错。有InternalODataRequestMessage
一个私有成员 requestMessage 类型ODataBatchOperationRequestMessage
。它似乎没有我可以添加客户端证书的任何属性。
我已经发布了关于该特定问题的另一个问题,如果我在此处提供的实施结果证明是问题,我将更改此答案。