向 WCF 脚手架 SOAP Web 服务添加授权 header

Adding an Authorization header to a WCF scaffolded SOAP web service

免责声明我从未使用过 SOAP Web 服务。完全没有。一点儿都没有。所以通道和 WCF 脚手架的概念让我有点困惑,所以我来了。

我被要求集成到使用基本身份验证的 SOAP XML Web 服务。 (例如授权 header、基本 xxxxxxxxxxxxxxxxxxxxxxxxxxxx <- 这是 Base64 编码 username:password)。我的项目在 .NET Core 中使用 C#。

我已经使用 Visual Studio WCF 连接服务发现来生成脚手架代码,这对我实例化所需的 objects 等非常有用,但是我的问题是我被要求使用 Basic身份验证,我不知道在哪里将这段代码注入到已经生成的脚手架中。我之前使用过基本身份验证,所以我理解 'how' 可以做到这一点,例如 REST API 等。只需 username:password,base64 编码并添加到授权 header。但是,我不确定如何为这个脚手架 SOAP Web 服务执行此操作。

我相信可以注入每个请求的代码,以添加您的自定义 headers,是:

        using (OperationContextScope scope = new OperationContextScope(IContextChannel or OperationContext)
        {
            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = new HttpRequestMessageProperty()
            {
                Headers =
                {
                    { "MyCustomHeader", Environment.UserName },
                    { HttpRequestHeader.UserAgent, "My Custom Agent"}
                }
            };
        // perform proxy operations... 
    }

OperationContextScope 需要 IContextChannel 或 OperationContext。我不知道要在这里添加什么。如果我查看我的脚手架代码,我可以在此处找到 Web 服务的 'client':

public partial class POSUserInformationManagerV1_2Client : System.ServiceModel.ClientBase<McaEndpointPosUserInformation.POSUserInformationManagerV1_2>, McaEndpointPosUserInformation.POSUserInformationManagerV1_2

我可以在这里找到 'channel',但这只是另一个界面,没有指定任何合同?

[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
public interface POSUserInformationManagerV1_2Channel : McaEndpointPosUserInformation.POSUserInformationManagerV1_2, System.ServiceModel.IClientChannel
{
}

我查找了 ChannelBase,它似乎应该接受实现一个或另一个通道接口的各种 objects(包括脚手架 POSUserInformationManagerV1_2Channel 使用的 IClientChannel)

    protected class ChannelBase<T> : IDisposable, IChannel, ICommunicationObject, IOutputChannel, IRequestChannel, IClientChannel, IContextChannel, IExtensibleObject<IContextChannel> where T : class
    {
        protected ChannelBase(ClientBase<T> client);

        [SecuritySafeCritical]
        protected IAsyncResult BeginInvoke(string methodName, object[] args, AsyncCallback callback, object state);
        [SecuritySafeCritical]
        protected object EndInvoke(string methodName, object[] args, IAsyncResult result);

但我仍然坚持我可以将什么放入 OperationContextScope 以将其适当地连接到 'channel'。我试过 POSUserInformationManagerV1_2Client 和相关的 Channel 接口,但都不会转换为 IContextChannel。有人有ideas/thoughts吗?

编辑:这是我尝试注入代码以添加 Auth HTTP header:

的地方
    public System.Threading.Tasks.Task<McaEndpointPosUserInformation.requestUserInformationResponse> requestUserInformationAsync(McaEndpointPosUserInformation.requestUserInformation request)
    {
        using (OperationContextScope scope = new OperationContextScope(request)
        {
            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = new HttpRequestMessageProperty()
            {
                Headers =
                {
                    { "MyCustomHeader", Environment.UserName },
                    { HttpRequestHeader.UserAgent, "My Custom Agent"}
                }
            };
        // perform proxy operations... 
    }
        return base.Channel.requestUserInformationAsync(request);
    }

问题原来是没有通过使用 'Basic' 将传输安全设置为:

                // Set the binding. Without this, the WCF call will be made as anonymous
                var binding = new BasicHttpsBinding();
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;