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

发布于 2025-02-09 04:44:11 字数 1255 浏览 0 评论 0 原文

我有一个从WSDL文件生成的客户端,并在.NET Core 3.1项目中使用它。我无法通过 clientcredentials basichttp(s)绑定设置授权标头。我用钩宾查看了我的要求。这是我的代码:

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" });

我已经尝试使用其他绑定,例如 wshtpbinding ,例如Microsoft文档建议: https://learn.microsoft.com/en-us/dotnet/dotnet/framework/wcf/wcf/wcf/feature-deture-details/feature-details/feature-details/transport-security-security-security-security-security-security-security-security-security-security-security-security-regin-使用基本认证

我在做什么错?

I have a client generated from a WSDL file and uses this in a .NET core 3.1 project. I can't set the Authorization header through ClientCredentials and a BasicHttp(s)Binding. I used hookbin to see my request. This is my code:

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" });

I already tried using other Bindings like WSHttpBinding like the Microsoft documentation suggests: https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-basic-authentication

What am i doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

老娘不死你永远是小三 2025-02-16 04:44:11

感谢: https://stackoverflow.com/a/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 to 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" });

Thanks to: https://stackoverflow.com/a/60714907/9124424
I found a solution, but i still wonder why the code in my question does not work

So you need to add an IClientMessageInspector and an 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;
        }
    }

And then you can add this IEndpointBehavior to the Endpoint in the client instance

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", 
quot;Basic --INSERT TOKEN--"}
                }));
var behavior = new AddHttpHeaderMessageEndpointBehavior(headers);
soapClient.Endpoint.EndpointBehaviors.Add(behavior);
soapClient.CallServiceMethod(new Request { Foo = "Bar" });
甜味拾荒者 2025-02-16 04:44:11

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

  • 需要删除 binding.security.transport.clientcredentialType = httpclientcredentialtype.basic; basic; ,否则它要求直接设置凭据。
  • set binding.security.mode = basichttpsecuritymode.transport; 用于使用https

For me Stutje's solution works perfect, except:

  • needed to remove binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;, otherwise it asking to set credentials directly.
  • set binding.Security.Mode = BasicHttpSecurityMode.Transport; to use https
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文