繁体   English   中英

未设置 C# .NET Core SOAP 客户端基本身份验证标头

[英]C# .NET Core SOAP Client basic auth header not set

我有一个从 WSDL 文件生成的客户端,并在 .NET core 3.1 项目中使用它。 我无法通过ClientCredentialsBasicHttp(s)Binding设置 Authorization 标头。 我使用 hookbin 来查看我的请求。 这是我的代码:

BasicHttpsBinding binding= new BasicHttpsBinding();

//for http
//binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress endpoint = new EndpointAddress("https://hookb.in/...");

var soapClient = new RandomServiceClient(binding, endpoint);
soapClient.ClientCredentials.UserName.UserName = "user";
soapClient.ClientCredentials.UserName.Password = "bla";

soapClient.CallServiceMethod(new Request { Foo = "Bar" });

我已经尝试使用其他绑定,如 Microsoft 文档建议的WSHttpBindinghttps ://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-basic-authentication

我究竟做错了什么?

感谢: https ://stackoverflow.com/a/60714907/9124424 我找到了解决方案,但我仍然想知道为什么我的问题中的代码不起作用

所以你需要添加一个IClientMessageInspector和一个IEndpointBehavior

    public class AddHttpHeaderMessageEndpointBehavior : IEndpointBehavior
    {
        private readonly IClientMessageInspector _httpHeaderMessageInspector;

        public AddHttpHeaderMessageEndpointBehavior(Dictionary<string, string> headers)
        {
            _httpHeaderMessageInspector = new HttpHeaderMessageInspector(headers);
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {

        }

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

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {

        }

        public void Validate(ServiceEndpoint endpoint)
        {

        }
    }
    
    public class HttpHeaderMessageInspector : IClientMessageInspector
    {
        private readonly Dictionary<string, string> _headers;

        public HttpHeaderMessageInspector(Dictionary<string, string> headers)
        {
            _headers = headers;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {

        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            if (request.Properties.Count == 0 || request.Properties[HttpRequestMessageProperty.Name] == null)
            {
                request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty());
            }
            var headersCollection = ((HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]).Headers;

            foreach (var header in _headers) headersCollection[header.Key] = header.Value;

            return null;
        }
    }

然后您可以将此IEndpointBehavior添加到客户端实例中的Endpoint

BasicHttpsBinding binding= new BasicHttpsBinding();

//for http
//binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress endpoint = new EndpointAddress("https://hookb.in/...");

var soapClient = new RandomServiceClient(binding, endpoint);
var headers = new Dictionary<string, string>
                {
                    {"Authorization", $"Basic --INSERT TOKEN--"}
                }));
var behavior = new AddHttpHeaderMessageEndpointBehavior(headers);
soapClient.Endpoint.EndpointBehaviors.Add(behavior);
soapClient.CallServiceMethod(new Request { Foo = "Bar" });

对我来说,Stutje 的解决方案非常完美,除了:

  • 需要删除binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; ,否则它要求直接设置凭据。
  • 设置binding.Security.Mode = BasicHttpSecurityMode.Transport; 使用 https

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM