dotnet / wcf

This repo contains the client-oriented WCF libraries that enable applications built on .NET Core to communicate with WCF services.
MIT License
1.7k stars 560 forks source link

Additional configuration required since upgrading packages to version 4.9.0. #4819

Open tjaz-brelih opened 2 years ago

tjaz-brelih commented 2 years ago

Describe the bug Since upgrading WCF client packages to version 4.9.0 the following error is thrown when trying to connect to a WCF service:

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

In previous versions (4.8.1 and earlier) registering the WCF client for dependency injection was achieved the following way:

var address = configuration.GetValue<string>("WcfServiceUrl");

services.AddScoped<IWcfService, WcfServiceClient>(opt =>
{
    var client = new WcfServiceClient(WcfServiceClient.EndpointConfiguration.IWcfService, address);
    client.ClientCredentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
    return client;
});

Note: IWcfService and WcfServiceClient are auto-generated by the Connected Service tool.

This exception can be fixed with some additional configuration when creating the WCF service client in Asp.Net Core project:

var address = configuration.GetValue<string>("WcfServiceUrl");

services.AddScoped<IWcfService, WcfServiceClient>(opt =>
{
    var client = new WcfServiceClient(WcfServiceClient.EndpointConfiguration.IWcfService, address);
    client.ClientCredentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;

    var binding = client.Endpoint.Binding as BasicHttpBinding;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
    binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Ntlm;

    return client;
});

Expected behavior Up until version 4.9.0 the additional configuration of ClientCredentialType and ProxyCredentialType was not necessary. I'm not sure if this change qualifies as a bug, but previous versions required less configuration. It seems that previous versions were able to negotiate authentication type automatically.

Additional context In our company we have a local WCF service that other Asp.Net Core projects communicate with. We add a reference to this WCF service through the Visual Studio 2022 "Connected Services" dialog. The WCF service authenticates users by using NTLM.

HongGit commented 2 years ago

@imcarolwang can you please see if you could repro this issue? If so, is this an issue with the WCF Connected Services?

imcarolwang commented 2 years ago

I can't reproduce the problem on my side, I'm using a test service with BasicHttpBinding, transport security mode and Windows as transport clientCredentialType.

@tjaz-brelih, are you using the same client code generated by the Connected Service tool in both the work and non-work scenarios? I wonder if this is caused by a change in the WCF CS tool or the WCF package. Can you provide a standalone application that reproduces the problem?

tjaz-brelih commented 2 years ago

@imcarolwang Yes, both the work and non-work scenarios use the same client code.

Another thing to note, when adding the connected service the tool automatically adds the necessary packages to project. In this case the tool adds the following package rules to project file:

<PackageReference Include="System.ServiceModel.Duplex" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.Federation" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.Http" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.Security" Version="4.8.*" />

So the additional configuration is only necessary when manually upgrading these packages to version 4.9.0. I'm using Visual Studio Community 2022 17.2.2, and the client code was generated with Microsoft.Tools.ServiceModel.Svcutil version 2.0.3.

As for a standalone application, I'll try creating a basic WCF service host that exhibits the same problems when adding to a project. The service I'm using in production is maintained by another team, I'll see if I can get some information on how the host is configured so I can try reproducing the issue.