【问题标题】:NTLM authentication in WCF calling .net core APIWCF 中的 NTLM 身份验证调用 .net 核心 API
【发布时间】:2020-01-14 16:01:03
【问题描述】:

我有一个 WCF 服务 (A),它使用以下配置调用另一个 WCF 服务 (B)。

<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
  <message clientCredentialType="UserName" algorithmSuite="Default" />
</security> 

我正在从 .net 核心 (v2.2) 服务调用服务 B。我有以下设置:

BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
basicHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Ntlm;
basicHttpBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

// doesn't have Default as the option. Only TripleDes
//basicHttpBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.TripleDes
basicHttpBinding.MaxReceivedMessageSize = int.MaxValue;
basicHttpBinding.ReceiveTimeout = new TimeSpan(250000000000);//Timespan in nanoseconds.

EndpointAddress endpointAddress = new EndpointAddress("http://");

customerServiceClient = new CustomerServiceClient(basicHttpBinding, endpointAddress);
NetworkCredential networkCredential = new NetworkCredential("user", "password", "domain");
customerServiceClient.ClientCredentials.Windows.ClientCredential = networkCredential;
customerServiceClient.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

我收到错误消息:身份验证失败,因为无法重用连接。下面是异常的部分堆栈:

{"Message":"Authentication failed because the connection could not be reused.","Data":{},"InnerException":{"Message":"Authentication failed because the connection could not be reused.","Data":{},"InnerException":null,"StackTrace":"   at System.Net.Http.HttpConnection.DrainResponseAsync(HttpResponseMessage response)\r\n   at System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean isProxyAuth, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken)\r\n   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)\r\n   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)\r\n   at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken)\r\n   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n   at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n...

请告诉我如何解决这个问题。此外,此 API 将部署到 PCF 中。

谢谢, 阿伦

【问题讨论】:

    标签: c# wcf .net-core


    【解决方案1】:

    目前NetCore不支持消息安全模式。因此,下面的语句将不起作用。

    basicHttpBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
    

    但是NetCore2.2支持TransportCredentialOnly安全模式的WCF服务。
    这是调用服务的示例。

     ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            NetworkCredential nc = new NetworkCredential("administrator", "abcd1234!");
            client.ClientCredentials.Windows.ClientCredential = nc;
            var result = client.TestAsync().Result;
            Console.WriteLine(result);
    

    添加连接服务引用后,绑定设置和端点已经在 Reference.cs 文件中配置。
    我们只需要修改默认的服务端点地址即可。

    然后我们在客户端配置 Windows 凭据。在我这边,它有效。 请确保您的客户项目基于AspNet Core2.2 另外,请参考官方 Github 仓库中的讨论。可能对你有用。
    https://github.com/dotnet/wcf/issues/2923
    如果有什么我可以帮忙的,请随时告诉我。

    【讨论】:

    • 非常感谢您在这里的时间和精力。但我仍然面临同样的问题 - “身份验证失败,因为无法重用连接。”。现在详细说明:“目前,NetCore 不支持消息安全模式”——这是否意味着如果服务要求消息安全,我们就无法从 .net 核心连接?我根本没有得到一个带有空构造函数的服务客户端。所以我求助于:customerServiceClient = new TrustedCustomerServiceClient(EndpointConfiguration.BasicHttpBinding_ITrustedCustomerService, "url");是的,我也读过那个讨论。
    • 是的。能否使用基于Core2.2 的Console 应用程序创建对服务的成功调用?您的 NetCore(V2.2) 服务是什么项目类型?我很困惑为什么你没有构造函数。是否使用 Microsoft WCF Web Service Reference Provider 并确保项目基于 Core2.2。
    • 我能够做到这一点 - @Abraham 你之前放置的链接提到了'AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);'。我把它放在代理的构造函数中,事情就开始工作了。非常感谢先生。会将您的帖子标记为答案。
    猜你喜欢
    • 2020-12-07
    • 2018-05-29
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 2019-02-23
    • 2020-03-03
    • 2010-10-25
    相关资源
    最近更新 更多