Web Services 调用第三方.asmx Web服务,客户端身份验证方案“Anonymous”禁止HTTP请求

brc7rcf0  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(197)

我需要调用第三方.asmx Web服务。此服务使用https。我有所需的证书(.pfx)。
当我调用该服务时,我收到以下错误:“HTTP请求被客户端身份验证方案”匿名“禁止。”
我的代码:

var certStore = new X509Store(StoreLocation.CurrentUser);
            certStore.Open(OpenFlags.ReadOnly);
            var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, "2fxb63ff3053ff35f4tf2362ad3ac1e8f8433a19", true);
            certStore.Close();
            var cert = certCollection[0];

            //Assign my xml
            AssinadorDigital.SignXml(xmlDoc, cert);
            xmlDoc.Save(@"C:\Test\doc.xml");

            // Do some staffs, add node etc
            
            ... Omitted for brevity

            XmlNode newNode = doc.DocumentElement;

            EndpointAddress ep = new(new Uri("https://nfe-homologacao.svrs.rs.gov.br/ws/NfeStatusServico/NfeStatusServico4.asmx"));
        
            var ws = new NFeWCFWebService.StatusServico.NFeStatusServico4SoapClient(
NFeWCFWebService.StatusServico.NFeStatusServico4SoapClient.EndpointConfiguration.NFeStatusServico4Soap12);
            ws.Endpoint.Address = ep;
            ws.ClientCredentials.ClientCertificate.Certificate = cert;

            var return = ws.nfeStatusServicoNFAsync(newNode).Result;

下面是Visual Studio添加的服务引用代码:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace NFeWCFWebService.StatusServico
{
    
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
    [System.ServiceModel.ServiceContractAttribute(Namespace="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4", ConfigurationName="NFeWCFWebService.StatusServico.NFeStatusServico4Soap")]
    public interface NFeStatusServico4Soap
    {
        
        [System.ServiceModel.OperationContractAttribute(Action="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4/nfeStatusServicoNF", ReplyAction="*")]
        [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
        System.Threading.Tasks.Task<NFeWCFWebService.StatusServico.nfeStatusServicoNFResponse> nfeStatusServicoNFAsync(NFeWCFWebService.StatusServico.nfeStatusServicoNFRequest request);
    }
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
    [System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
    public partial class nfeStatusServicoNFRequest
    {
        
        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4", Order=0)]
        public System.Xml.XmlNode nfeDadosMsg;
        
        public nfeStatusServicoNFRequest()
        {
        }
        
        public nfeStatusServicoNFRequest(System.Xml.XmlNode nfeDadosMsg)
        {
            this.nfeDadosMsg = nfeDadosMsg;
        }
    }
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
    [System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
    public partial class nfeStatusServicoNFResponse
    {
        
        [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4", Order=0)]
        [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
        public System.Xml.XmlNode nfeResultMsg;
        
        public nfeStatusServicoNFResponse()
        {
        }
        
        public nfeStatusServicoNFResponse(System.Xml.XmlNode nfeResultMsg)
        {
            this.nfeResultMsg = nfeResultMsg;
        }
    }
    
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
    public interface NFeStatusServico4SoapChannel : NFeWCFWebService.StatusServico.NFeStatusServico4Soap, System.ServiceModel.IClientChannel
    {
    }
    
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.3")]
    public partial class NFeStatusServico4SoapClient : System.ServiceModel.ClientBase<NFeWCFWebService.StatusServico.NFeStatusServico4Soap>, NFeWCFWebService.StatusServico.NFeStatusServico4Soap
    {
        
        /// <summary>
        /// Implement this partial method to configure the service endpoint.
        /// </summary>
        /// <param name="serviceEndpoint">The endpoint to configure</param>
        /// <param name="clientCredentials">The client credentials</param>
        static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);
        
        public NFeStatusServico4SoapClient(EndpointConfiguration endpointConfiguration) : 
                base(NFeStatusServico4SoapClient.GetBindingForEndpoint(endpointConfiguration), NFeStatusServico4SoapClient.GetEndpointAddress(endpointConfiguration))
        {
            this.Endpoint.Name = endpointConfiguration.ToString();
            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
        }
        
        public NFeStatusServico4SoapClient(EndpointConfiguration endpointConfiguration, string remoteAddress) : 
                base(NFeStatusServico4SoapClient.GetBindingForEndpoint(endpointConfiguration), new System.ServiceModel.EndpointAddress(remoteAddress))
        {
            this.Endpoint.Name = endpointConfiguration.ToString();
            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
        }
        
        public NFeStatusServico4SoapClient(EndpointConfiguration endpointConfiguration, System.ServiceModel.EndpointAddress remoteAddress) : 
                base(NFeStatusServico4SoapClient.GetBindingForEndpoint(endpointConfiguration), remoteAddress)
        {
            this.Endpoint.Name = endpointConfiguration.ToString();
            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
        }
        
        public NFeStatusServico4SoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
                base(binding, remoteAddress)
        {
        }
        
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
        System.Threading.Tasks.Task<NFeWCFWebService.StatusServico.nfeStatusServicoNFResponse> NFeWCFWebService.StatusServico.NFeStatusServico4Soap.nfeStatusServicoNFAsync(NFeWCFWebService.StatusServico.nfeStatusServicoNFRequest request)
        {
            return base.Channel.nfeStatusServicoNFAsync(request);
        }
        
        public System.Threading.Tasks.Task<NFeWCFWebService.StatusServico.nfeStatusServicoNFResponse> nfeStatusServicoNFAsync(System.Xml.XmlNode nfeDadosMsg)
        {
            NFeWCFWebService.StatusServico.nfeStatusServicoNFRequest inValue = new NFeWCFWebService.StatusServico.nfeStatusServicoNFRequest();
            inValue.nfeDadosMsg = nfeDadosMsg;
            return ((NFeWCFWebService.StatusServico.NFeStatusServico4Soap)(this)).nfeStatusServicoNFAsync(inValue);
        }
        
        public virtual System.Threading.Tasks.Task OpenAsync()
        {
            return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginOpen(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndOpen));
        }
        
        public virtual System.Threading.Tasks.Task CloseAsync()
        {
            return System.Threading.Tasks.Task.Factory.FromAsync(((System.ServiceModel.ICommunicationObject)(this)).BeginClose(null, null), new System.Action<System.IAsyncResult>(((System.ServiceModel.ICommunicationObject)(this)).EndClose));
        }
        
        private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
        {
            if ((endpointConfiguration == EndpointConfiguration.NFeStatusServico4Soap))
            {
                System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
                result.MaxBufferSize = int.MaxValue;
                result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
                result.MaxReceivedMessageSize = int.MaxValue;
                result.AllowCookies = true;
                result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
                return result;
            }
            if ((endpointConfiguration == EndpointConfiguration.NFeStatusServico4Soap12))
            {
                System.ServiceModel.Channels.CustomBinding result = new System.ServiceModel.Channels.CustomBinding();
                System.ServiceModel.Channels.TextMessageEncodingBindingElement textBindingElement = new System.ServiceModel.Channels.TextMessageEncodingBindingElement();
                textBindingElement.MessageVersion = System.ServiceModel.Channels.MessageVersion.CreateVersion(System.ServiceModel.EnvelopeVersion.Soap12, System.ServiceModel.Channels.AddressingVersion.None);
                result.Elements.Add(textBindingElement);
                System.ServiceModel.Channels.HttpsTransportBindingElement httpsBindingElement = new System.ServiceModel.Channels.HttpsTransportBindingElement();
                httpsBindingElement.AllowCookies = true;
                httpsBindingElement.MaxBufferSize = int.MaxValue;
                httpsBindingElement.MaxReceivedMessageSize = int.MaxValue;
                result.Elements.Add(httpsBindingElement);
                return result;
            }
            throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
        }
        
        private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
        {
            if ((endpointConfiguration == EndpointConfiguration.NFeStatusServico4Soap))
            {
                return new System.ServiceModel.EndpointAddress("https://nfe-homologacao.svrs.rs.gov.br/ws/NfeStatusServico/NfeStatusServico4.asmx" +
                        "");
            }
            if ((endpointConfiguration == EndpointConfiguration.NFeStatusServico4Soap12))
            {
                return new System.ServiceModel.EndpointAddress("https://nfe-homologacao.svrs.rs.gov.br/ws/NfeStatusServico/NfeStatusServico4.asmx" +
                        "");
            }
            throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
        }
        
        public enum EndpointConfiguration
        {
            
            NFeStatusServico4Soap,
            
            NFeStatusServico4Soap12,
        }
    }
}

PS:我发现了一些关于使用app.config的旧帖子,如下所示,但我不知道如何使用.net6。

<binding name="NfeConsulta2Soap12">
        ...
        <httpsTransport authenticationScheme="Digest" requireClientCertificate="true" ... />
     </binding>
qhhrdooz

qhhrdooz1#

现在很好用,以防将来有人需要。
用于.net 6
我只是更改了这部分代码:

var binding = new BasicHttpBinding();
       
        binding.Security.Mode = BasicHttpSecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
        binding.TextEncoding = Encoding.UTF8;
        binding.TransferMode = TransferMode.Buffered;
        binding.AllowCookies = false;

        EndpointAddress ep = new(new Uri("https://nfe-homologacao.svrs.rs.gov.br/ws/NfeStatusServico/NfeStatusServico4.asmx"));

        var ws = new NFeWCFWebService.StatusServico.NFeStatusServico4SoapClient(binding, ep);

        ws.ClientCredentials.ServiceCertificate.DefaultCertificate = cert;
              
        var retorno = ws.nfeStatusServicoNFAsync(newNode).Result;

相关问题