我们有一个使用证书保护的 ODATA 服务。我们正在使用 AddWebReference 在我们的 C# 代码中获取代理。
有没有办法将我们证书存储中的证书附加到这个生成的代理类?
我们可以使用 HTTPClient
添加证书, 但我们想避免使用 HTTPClient
与我们的 ODATA 服务对话并更喜欢使用 AddWebReference 方法。
最佳答案
我想这对您来说可能为时已晚 3 年,但希望其他人会得到帮助。
This article实际上非常详细地解释了需要什么。
您需要添加 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
具有您需要的证书的属性(property):// 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 DataServices 5+(不完全工作)
现在,如果您使用 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
是类型而不是 HttpWebRequestMessage
导致 InvalidCastExceptions
.这实际上是我最终提出这个问题的原因。似乎只有批处理操作才会出错。 InternalODataRequestMessage
有一个 ODataBatchOperationRequestMessage
类型的私有(private)成员 requestMessage .它似乎没有我可以添加客户端证书的任何属性。我已发布 another question关于该特定问题,如果我在此处提供的实现成为问题,将更改此答案。
关于certificate - 如何将证书附加到 ODATA 服务的 C# 客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4351418/