.Net Core 2.0 call to WCF client configuration

回眸只為那壹抹淺笑 提交于 2020-07-23 08:38:13

问题


I have a .NET Core 2.0 application and need to call a WCF client from one of its controllers, and pass the user credentials for authentication.

Within the .net core app I created a reference for the WCF client using the Connected Services (WCF Web Service Reference Provider) and now in a process of configuring the call. Note that I can use the same endpoint form a 4.6 framework application without any problems.

Here's my code:

        var binding = new BasicHttpBinding {Security = {Mode = BasicHttpSecurityMode.Transport}};

        var address = new EndpointAddress("https://my-endpoint.asmx");

        var client  = new MyAppSoapClient(binding, address);

        var credentials = CredentialCache.DefaultNetworkCredentials; 

        client.ClientCredentials.Windows.ClientCredential = credentials;
        client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

        var response = client.GetStuff("param").Result;

I face a number of problems:

It has to be a https call
I need to pass the currently log in user credentials to the call

The current error I get is as follows:

The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate, NTLM'

Also the ConnectedService.json (created automativcally by WCF Web Service Reference Provider) has a predefined endpoint Uri.. I don't understand why I need to pass the address to the client manually (the code seems to be forcing me to do so).. ideally I'd like to get this dynamically amended in json depending on environment.

Thanks.


回答1:


I noticed that you passed the current logged-in user as a Windows credential (which is also necessary for enabling impersonation), but you did not explicitly set the client credentials for the transport layer security.

BasicHttpBinding binding = new BasicHttpBinding();
            binding.Security.Mode = BasicHttpSecurityMode.Transport;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

Also the ConnectedService.json (created automativcally by WCF Web Service Reference Provider) has a predefined endpoint Uri.. I don't understand why I need to pass the address to the client manually (the code seems to be forcing me to do so)

You can modify the method of automatic generation of proxy client to construct client proxy class (located in the reference.cs)
Modify the binding security

private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
        {
            if ((endpointConfiguration == EndpointConfiguration.WebService1Soap))
            {
                System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
                result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
                result.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
                result.MaxBufferSize = int.MaxValue;
                result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
                result.MaxReceivedMessageSize = int.MaxValue;
                result.AllowCookies = true;
                return result;
            }

Modify the endpoint.

  private static System.ServiceModel.EndpointAddress GetEndpointAddress(EndpointConfiguration endpointConfiguration)
    {
        if ((endpointConfiguration == EndpointConfiguration.WebService1Soap))
        {
            return new System.ServiceModel.EndpointAddress("http://10.157.13.69:8001/webservice1.asmx");

Construct the client proxy class.

ServiceReference1.WebService1SoapClient client = new WebService1SoapClient(WebService1SoapClient.EndpointConfiguration.WebService1Soap);
            client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
            client.ClientCredentials.Windows.ClientCredential.Password = "123456";

Feel free to let me know if there is anything I can help with.




回答2:


My binding was missing the security Ntlm credential type (see below).

Problem solved.

    var binding = new BasicHttpBinding {Security = {Mode = BasicHttpSecurityMode.Transport,
        Transport = new HttpTransportSecurity(){ClientCredentialType = HttpClientCredentialType.Ntlm } }};


来源:https://stackoverflow.com/questions/55141046/net-core-2-0-call-to-wcf-client-configuration

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!