通过生成的 WebServiceClient 进行 WCF Soap 基本身份验证

WCF Soap Basic Authentication through the Generated WebServiceClient

我正在尝试使用 WCF Web 服务参考来使用 SOAP Web 服务。

我已经能够使用 System.Web.Servicees Web 服务参考在 .NET 4.8 框架项目中成功使用 SOAP Web 服务。但是我需要在 .NET Core 项目中使用 Web 服务。从 WSDL 生成 class 的 WCF 不同于 .NET 框架 Web 服务。看来您现在必须使用生成的 WebServiceClient 与 Web 服务进行交互。

我认为 Web 服务需要基本身份验证,因为我能够在 .NET Framework 项目中使用基本身份验证进行身份验证。

这是我在尝试执行 Web 服务的一种方法时收到的错误消息。

  System.ServiceModel.Security.MessageSecurityException
  HResult=0x80131500
  Message=The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was ''.
  Source=System.Private.ServiceModel

这是我实例化客户端并调用方法的代码

    var callContext = new CAdxCallContext();
    callContext.codeLang = "ENG";
    callContext.poolAlias = "BGRTEST";
    callContext.requestConfig = "adxwss.trace.on=on&adxwss.trace.size=16384&adonix.trace.on=on&adonix.trace.level=3&adonix.trace.size=8";


    var proxy = new CAdxWebServiceXmlCCClient();
    proxy.ClientCredentials.UserName.UserName = "username";
    proxy.ClientCredentials.UserName.Password = "password";

    string _InputXml = "<PARAM>" +
    "<GRP ID= \"GRP1\">" +
    "<FLD NAME = \"ITMREF\">" + 100001 + "</FLD>" +
    "</GRP>" +
    "</PARAM>";

    try
    {
        var response = proxy.run(callContext, "BGR_SIEPRO", _InputXml);
    }
    finally
    {
        proxy.Close();
    }

我的 WCF 服务连接: WCF Connected Service Screenshot

自动生成的 WCF WebServiceClient:https://github.com/abiddle-bgr/Test/blob/main/CAdxWebServiceXmlCCClient.cs

您是否设置了安全传输模式?类似这样:Basic Authentication in WCF client.

   <security mode="TransportCredentialOnly">
      <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
   </security>

在代码中,设置代理class允许模拟

proxy.ClientCredentials.Windows.AllowedImpersonationLevel =    
         System.Security.Principal.TokenImpersonationLevel.Impersonation;

你可以看看this post.

我最终不得不通过创建自定义端点并将其作为自定义端点行为添加到代理来手动注入 headers。

 var proxy = new CAdxWebServiceXmlCCClient();
 proxy.Endpoint.EndpointBehaviors.Add(new CustomEndpoint());

 public class ClientMessageInspector : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            // Nothing Here
            Console.Write(reply.ToString());
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
            httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " +
                Convert.ToBase64String(Encoding.ASCII.GetBytes("USERNAME" + ":" +
                    "PASSWORD"));
            request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestProperty);
            return null;
        }
    }

    public class CustomEndpoint : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
            // Nothing here
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            // Nothing here
        }

        public void Validate(ServiceEndpoint endpoint)
        {
            // Nothing here
        }
    }