如何添加ClientCeritifcates,HTTP请求被禁止使用客户端身份验证方案' Anonymous'

时间:2017-04-01 23:56:18

标签: c# web-services soap messagecontract

从自动生成的Web服务代理类调用方法时出现以下错误:

  

System.ServiceModel.Security.MessageSecurityException未处理
  HResult = -2146233087 Message =禁止使用HTTP请求   客户端身份验证方案' Anonymous'。来源= mscorlib程序
  堆栈跟踪:       服务器堆栈跟踪:          在System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest)   请求,HttpWebResponse响应,WebException responseException,   HttpChannelFactory' 1工厂)          在System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest)   请求,HttpWebResponse响应,HttpChannelFactory' 1工厂,   WebException responseException,ChannelBinding channelBinding)          在System.ServiceModel.Channels.HttpChannelFactory' 1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan)   超时)          在System.ServiceModel.Channels.RequestChannel.Request(消息消息,TimeSpan超时)          在System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息   消息,TimeSpan超时)          在System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,   对象[]输出,TimeSpan超时)          在System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,   对象[]出局)          在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage)   methodCall,ProxyOperationRuntime操作)          在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage   信息)       在[0]处重新抛出异常:          在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage   reqMsg,IMessage retMsg)          在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&   msgData,Int32类型)          在RPS.LoteNFe.LoteNFeSoap.TesteEnvioLoteRPS(TesteEnvioLoteRPSRequest)   请求)          在RPS.LoteNFe.LoteNFeSoapClient.RPS.LoteNFe.LoteNFeSoap.TesteEnvioLoteRPS(TesteEnvioLoteRPSRequest)   请求)在c:\ Users \ Marcelo \ Documents \ Visual Studio中   2015 \ Projects \ RPS \ RPS \ Service References \ LoteNFe \ Reference.cs:第560行          在C:\ Users \ Marcelo \ Documents \ Visual中的RPS.LoteNFe.LoteNFeSoapClient.TesteEnvioLoteRPS(Int32 VersaoSchema,String MensagemXML)   Studio 2015 \ Projects \ RPS \ RPS \ Service   参考文献\ LoteNFe \ Reference.cs:第567行          at RPS.Assinador.button5_Click(Object sender,EventArgs e)在c:\ Users \ Marcelo \ Documents \ Visual Studio中   2015 \ Projects \ RPS \ RPS \ Assinador.cs:第76行          在System.Windows.Forms.Control.OnClick(EventArgs e)          在System.Windows.Forms.Button.OnClick(EventArgs e)          在System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)          在System.Windows.Forms.Control.WmMouseUp(消息& m,MouseButtons按钮,Int32点击)          在System.Windows.Forms.Control.WndProc(消息& m)          在System.Windows.Forms.ButtonBase.WndProc(消息& m)          在System.Windows.Forms.Button.WndProc(消息& m)          在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)          在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)          在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)          在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)          在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr)   dwComponentID,Int32原因,Int32 pvLoopData)          在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32)   原因,ApplicationContext上下文)          在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32)   原因,ApplicationContext上下文)          在System.Windows.Forms.Application.Run(Form mainForm)          在C:\ Users \ Marcelo \ Documents \ Visual Studio 2015 \ Projects \ RPS \ RPS \ Program.cs中的RPS.Program.Main():第19行          在System.AppDomain._nExecuteAssembly(RuntimeAssembly程序集,String [] args)          在System.AppDomain.ExecuteAssembly(String assemblyFile,Evidence assemblySecurity,String [] args)          在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()          在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)          在System.Threading.ExecutionContext.RunInternal(ExecutionContext   executionContext,ContextCallback回调,对象状态,布尔值   preserveSyncCtx)          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean   preserveSyncCtx)          在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)          at System.Threading.ThreadHelper.ThreadStart()InnerException:System.Net.WebException          的HResult = -2146233079          消息=远程服务器返回错误:(403)禁止。          来源=系统          堆栈跟踪:               在System.Net.HttpWebRequest.GetResponse()               在System.ServiceModel.Channels.HttpChannelFactory' 1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan)   超时)          的InnerException:

这是一个叫它的方式

X509Certificate2 x509Certificate = new X509Certificate2();
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = ((X509Certificate2Collection)store.Certificates).Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection collection1 = X509Certificate2UI.SelectFromCollection(collection, "Certificados disponiveis", "Selecione o certificado", X509SelectionFlag.SingleSelection);
x509Certificate = collection1[0];

LoteNFeSoapClient loteNFe = new LoteNFeSoapClient();
loteNFe.ClientCredentials.ClientCertificate.SetCertificate(x509Certificate.Subject, StoreLocation.CurrentUser, StoreName.My);
Retorno.Text = loteNFe.TesteEnvioLoteRPS(1, Assinado.Text);

我如何添加此Web服务引用:

在MS Visual Studio 2013社区中,Project > Add > Service Reference

Service Reference window

Service Reference advanced settings window

Obs:这些是默认配置。这是一个市政政府网络服务,用于发送所提供的运输或物流服务的电子发票。

我已经阅读了添加证书所需的地方:

LoteNFeSoapClient loteNFe = new LoteNFeSoapClient();
loteNFe.ClientCertificates.Add(clientCertificate);

但它不可能因为:

  1. 此自动生成的Web服务类不会从类继承 这个方法ClientCertificates.Add()就像HttpWebClientProtocol类一样。
  2. LoteNFeSoapClient()类已经从a继承 使messagecontract与之间的值匹配的接口 请求和回复。
  3. 在c#中,一个类不能有多个基类。
  4. 那么,可以做些什么呢?提前谢谢。

1 个答案:

答案 0 :(得分:0)

解决了,我刚刚使用wsdl.exe通过命令行生成了webservice代理类,这个类现在继承自System.Web.Services.Protocols.SoapHttpClientProtocol,所以我可以使用

添加证书
LoteNFe loteNFe = new LoteNFe();
loteNFe.ClientCertificates.Add(x509Certificate);

注意:通过命令行生成的类与使用VS2013 UI生成的类完全不同。