System.InvalidOperationException: No authentication handler is registered for the scheme 'Negotiate'. The registered schemes are: Windows. Did you forget to call AddAuthentication().Add[SomeAuthHandler]("Negotiate",...)
See original GitHub issueWe’re using transport Windows authentication.
Client: ((BasicHttpsBinding)binding).Security.Mode = BasicHttpsSecurityMode.Transport; ((BasicHttpsBinding)binding).Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
Server: var builder = WebApplication.CreateBuilder(args);
// Add services to the container. builder.Services.AddServiceModelServices(); builder.Services.AddServiceModelMetadata();
builder.Services.AddServiceModelConfigurationManagerFile(“wcf.config”);
builder.Services.AddAuthentication(IISDefaults.AuthenticationScheme); builder.Services.AddAuthorization(); builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<IServiceBehavior, UseRequestHeadersForMetadataAddressBehavior>();
Up to version 1.1.0-alpha.35, it was working without error. After alpha.35, the error we receive is:
System.InvalidOperationException: No authentication handler is registered for the scheme ‘Negotiate’. The registered schemes are: Windows. Did you forget to call AddAuthentication().AddSomeAuthHandler? at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme) at CoreWCF.Channels.RequestDelegateHandler.HandleRequest(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at CoreWCF.Channels.ServiceModelHttpMiddleware.InvokeAsync(HttpContext context) at CoreWCF.Channels.MetadataMiddleware.InvokeAsync(HttpContext context) at Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.InvokeCore(HttpContext context, PathString matchedPath, PathString remainingPath) at Microsoft.AspNetCore.Server.IIS.Core.IISHttpContextOfT`1.ProcessRequestAsync()
Issue Analytics
- State:
- Created a year ago
- Comments:13 (5 by maintainers)
Top GitHub Comments
In case it helps, here’s a complete walkthrough showing how to reproduce this problem. It’s fairly simple and just boils down to this: a .NET Framework WCF client app is not able to call a CoreWCF server app that requires Windows authentication – unless the client changes the default impersonation mode from Identification to Delegate or None.
This repo includes the completed demo: https://github.com/mvarblow/CoreWcfAuthDemo
Create the CoreWCF app which requires Windows authentication
Add authentication and authorization services in Program.cs:
Replace this line:
With these three lines:
Add [Authorize] attribute to Service.GetData method in IService.cs
Start debugging in VS. Copy the service WSDL URL, e.g. https://localhost:7209/service.svc?wsdl
Create a .NET 7 Client Application
Create a new console application:
dotnet new console --name CoreWCFDemoClient --framework net7.0
Right-click on the project in VS and use Add > Service Reference. Pick WCF Web Service. Paste in the service URL for the running Core WCF service. Click through the rest of the wizard.
Add this to the CoreWCFDemoClient Program.cs:
Run the client. It should print:
Create a .NET Framework Client Application
Now, create a .NET Framework console application from Visual Studio. Again, right-click on the project, Add Service Reference. Paste in the service WSDL URL and complete the dialog. In Program.cs add the following to the Main method:
Run the legacy client. It should print:
You entered: 12
Everything works fine as long as you run the CoreWCF service from the command line using Kestrel.
Host the Core WCF Server in IIS
Stop running CoreWCFDemoServer. Now let’s deploy it to IIS. Publish the CoreWCFDemoServer project to a folder. In IIS, create a new site using the publish folder as the physical path. Use the same port number that was previously used for running CoreWCFDemoServer from Visual Studio.
Change the site’s app pool to “No managed code”.
Enable Windows Authentication and disable Anonymous Authentication for the CoreWCFDemoServer site in IIS Manager.
Now run the CoreWCFDemoClient. It should again run successfully and print:
Now run the LegacyWCFClient. It will fail.
If you change the allowed impersonation level in the LegacyWCFClient to None or Delegation before calling the service then the call succeeds, e.g.
or
But with the default value it fails:
Summary
With a CoreWCF service configured to require Windows authentication, .NET Core clients work fine. But .NET Framework clients fail if using the default impersonation level.
It appears that Windows authentication is working successfully in IIS. We can see the successful authentication events in the security event log. But it appears that Microsoft.AspNetCore.Authentication.Negotiate does not flow the user principle over into ASP.NET Core / CoreWCF?
This is preventing us from successfully porting our application, which has legacy callers which need to continue working with the new service. The legacy callers use the default impersonation level.
It solved the problem when the client is using:
or client.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.None;
The default is TokenImpersonationLevel.Identification. The error received in the client is:
System.ServiceModel.Security.MessageSecurityException: ‘The HTTP request is unauthorized with client authentication scheme ‘Negotiate’. The authentication header received from the server was ‘Negotiate,NTLM’.’
I cannot ask to all the clients to modify their code to use TokenImpersonationLevel.None . I’m sure this is only something missing in my service configuration. Once again, it was working properly up to version 1.1.0-alpha.35.