CoreWCF服务迁移后WCF客户端NTLM身份认证401问题求助
问题:CoreWCF迁移后WCF客户端返回401认证失败,REST接口正常
背景
我正在将托管多个REST API和WCF接口的.NET 4.8应用迁移至ASP.NET Core(.NET 8),使用CoreWCF迁移WCF接口。因客户端存在大量依赖,无法修改客户端代码。
REST客户端(正常工作)
REST请求的客户端代码可正常调用迁移后的服务:
using (HttpClientHandler handler = new HttpClientHandler()) { handler.UseDefaultCredentials = true; using (HttpClient client = new HttpClient(handler)) { var response = client.GetAsync($"https://localhost:44375/api/interfaces").Result; } }
WCF客户端(返回401错误)
绑定初始化代码
private static void EnsureWCFServiceBindings() { if (transportBinding == null) { XmlDictionaryReaderQuotas readerQuotas = new XmlDictionaryReaderQuotas(); readerQuotas.MaxDepth = 2147483647; readerQuotas.MaxStringContentLength = 2147483647; readerQuotas.MaxArrayLength = 2147483647; readerQuotas.MaxBytesPerRead = 2147483647; readerQuotas.MaxNameTableCharCount = 2147483647; HttpTransportSecurity httpTransportSecurity = new HttpTransportSecurity(); httpTransportSecurity.ClientCredentialType = HttpClientCredentialType.Ntlm; httpTransportSecurity.ProxyCredentialType = HttpProxyCredentialType.Ntlm; httpTransportSecurity.Realm = "mydomain.com"; BasicHttpMessageSecurity basicHttpMessageSecurity = new BasicHttpMessageSecurity(); basicHttpMessageSecurity.ClientCredentialType = BasicHttpMessageCredentialType.UserName; basicHttpMessageSecurity.AlgorithmSuite = SecurityAlgorithmSuite.Default; BasicHttpsSecurity basicHttpsSecurity = new BasicHttpsSecurity { Mode = BasicHttpsSecurityMode.Transport, Transport = httpTransportSecurity, Message = basicHttpMessageSecurity }; BasicHttpsBinding basicHttpsBinding = new BasicHttpsBinding { CloseTimeout = TimeSpan.FromMinutes(5), OpenTimeout = TimeSpan.FromMinutes(5), ReceiveTimeout = TimeSpan.FromMinutes(10), SendTimeout = TimeSpan.FromMinutes(5), AllowCookies = false, BypassProxyOnLocal = false, HostNameComparisonMode = HostNameComparisonMode.StrongWildcard, MaxBufferSize = 2147483647, MaxBufferPoolSize = 0, MaxReceivedMessageSize = 2147483647, MessageEncoding = WSMessageEncoding.Text, TextEncoding = Encoding.UTF8, TransferMode = TransferMode.Buffered, ReaderQuotas = readerQuotas, Security = basicHttpsSecurity }; transportBinding = basicHttpsBinding; } if (clientBuildClient == null) { clientBuildClient = new EndpointAddress(string.Format("{0}{1}", "https://localhost:44375/", "BuildClient.svc")); } }
调用代码
MyCommunicationClient myClient = new MyCommunicationClient(WCFBindings.TransportBinding, WCFBindings.EndPointBuildClient); ResultObject response = myClient.CallService(serviceRequestParameter);
服务端Program.cs配置
builder.Services.AddHttpContextAccessor(); builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); builder.Services.AddAuthorization(options => { options.FallbackPolicy = options.DefaultPolicy; options.AddPolicy("RequireWindowsAuth", policy => { policy.RequireAuthenticatedUser(); policy.AddAuthenticationSchemes(NegotiateDefaults.AuthenticationScheme); }); }); builder.WebHost.UseIISIntegration(); // some more code here app.UseServiceModel(serviceBuilder => { serviceBuilder.AddService<BuildClient>((serviceOptions) => { }) .AddServiceEndpoint<BuildClient, IBuildClient>(new BasicHttpBinding { Security = new BasicHttpSecurity { Mode = BasicHttpSecurityMode.Transport, Transport = new HttpTransportSecurity { ClientCredentialType = HttpClientCredentialType.Windows, AlwaysUseAuthorizationPolicySupport = true, Realm = "mydomain.com" } } }, "/BuildClient.svc"); }); var serviceMetadataBehavior = app.Services.GetRequiredService<ServiceMetadataBehavior>(); serviceMetadataBehavior.HttpGetEnabled = true; serviceMetadataBehavior.HttpsGetEnabled = true; IHttpContextAccessor httpContextAccessor = app.Services.GetRequiredService<IHttpContextAccessor>(); IdentityProvider.Configure(httpContextAccessor); app.UseAuthentication(); app.UseAuthorization();
IIS Express配置
{ "iisSettings": { "windowsAuthentication": true, "anonymousAuthentication": false, "iisExpress": { "applicationUrl": "http://localhost:50228", "sslPort": 44375 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } }, "BuildService": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "http://localhost:50228;https://localhost:44375", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } }
已尝试的操作
- 自定义NtlmAuthenticationHandler后,REST请求可正常认证,但WCF请求仍无用户信息且返回401。
- 尝试多种
HttpClientCredentialType配置均无效。
需求
求指导如何配置服务端使WCF调用能正确认证用户。
内容的提问来源于stack exchange,提问作者Tomtom
相关产品推荐
相关产品推荐

