【问题标题】:USCG PSIX Web Service returning auth errorUSCG PSIX Web 服务返回身份验证错误
【发布时间】:2021-07-01 17:34:42
【问题描述】:

美国海岸警卫队运行一个名为 PSIX 的 SOAP Web 服务:

最近一段时间访问该Web服务的一些软件开始报错,从PSIX返回的错误是: The HTTP request was forbidden with client authentication scheme 'Anonymous'.

网站上的证书有问题,但只要我们访问该服务(一年半多一点)就一直是这样。

我在 USCG 网站上没有提到您需要任何类型的身份验证才能访问该服务 - 所以我不确定该怎么做。也没有提供服务的联系方式,我可以找到询问他们是否改变了他们方面的一些东西 - 我已经提交了一个关于这个问题的问题的评论表。

使用 Microsoft WCF Web Service Reference Provider 将服务添加到 .NET Core 项目中。如果它使用这个静态辅助方法,我们会创建一个实例。

关于如何绕过错误的任何想法?

private static PSIXDataSoap ServiceProxy
{
    get {
        try
        {
            if (_serviceProxy == null)
            {
                BasicHttpBinding binding = null;
                binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); //Force use SSL, otherwise you get "expected http"

                binding.MaxReceivedMessageSize = 20000000;
                binding.MaxBufferSize = 20000000;
                binding.MaxBufferPoolSize = 20000000;
                binding.AllowCookies = true;

                var factory = new ChannelFactory<PSIXDataSoap>(binding, new EndpointAddress("https://psix.uscg.mil/xml/PSIXData.asmx"));

                //Tell it: Yes, I know the Coast Guard's Certificate is invalid...
                factory.Credentials.ServiceCertificate.SslCertificateAuthentication =
                    new X509ServiceCertificateAuthentication()
                    {
                        CertificateValidationMode = X509CertificateValidationMode.None,
                        RevocationMode = X509RevocationMode.NoCheck
                    };

                _serviceProxy = factory.CreateChannel();
            }

            return _serviceProxy;
        }
        catch (Exception)
        {
            return null;
        }
    }
}

然后像这样访问代理:

var psixResponse = await ServiceProxy.getVesselSummaryAsync(vesselId_str, vesselName_str, callsign_str, vin_str, hin_str, flag_str, service_str, buildYear_str);

【问题讨论】:

    标签: c# wcf .net-core soap


    【解决方案1】:

    以下代码效果很好。如果它在您的计算机上失败,则可能是 TLS 问题。 :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string URL = "https://cgmix.uscg.mil/xml/PSIXData.asmx?WSDL";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(URL);
            }
        }
    }
    

    【讨论】:

    • 我也可以检索 WSDL,但是尝试运行任何操作,例如 getVesselSummaryAsync 都会导致错误。
    • 为什么有结果还需要访问代理。只需要解析xml结果即可。
    【解决方案2】:

    我猜美国海岸警卫队改变了他们网络服务的 URL。所以我:

    • 删除并重新添加了 WCF 连接服务参考
    • 更改了我的服务代理助手方法以使用新的 URL(我认为这是我的问题的根本原因)。

    至于为什么我需要特殊的辅助方法而不是从内置初始化程序创建服务引用,我认为主要是因为:

    • 我需要绕过证书错误
    • 我需要增加默认消息/缓冲区大小,因为其中一些调用会返回很多信息。

    无论如何,新的帮助方法解决了我的问题:

    private static PSIXDataSoap ServiceProxy
    {
        get {
            try
            {
                if (_serviceProxy == null)
                {
                    BasicHttpBinding binding = null;
                    binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); //Force use SSL, otherwise you get "expected http"
    
                    binding.MaxReceivedMessageSize = 20000000;
                    binding.MaxBufferSize = 20000000;
                    binding.MaxBufferPoolSize = 20000000;
                    binding.AllowCookies = true;
    
                    //var factory = new ChannelFactory<PSIXDataSoap>(binding, new EndpointAddress("https://psix.uscg.mil/xml/PSIXData.asmx"));
                    var factory = new ChannelFactory<PSIXDataSoap>(binding, new EndpointAddress("https://cgmix.uscg.mil/xml/PSIXData.asmx")); //<--- NEW URL
                    //Tell it: Yes, I know the Coast Guard's Certificate is invalid...
                    factory.Credentials.ServiceCertificate.SslCertificateAuthentication =
                        new X509ServiceCertificateAuthentication()
                        {
                            CertificateValidationMode = X509CertificateValidationMode.None,
                            RevocationMode = X509RevocationMode.NoCheck
                        };
    
                    _serviceProxy = factory.CreateChannel();
                }
    
                return _serviceProxy;
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      • 2019-12-17
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多