【问题标题】:Calling WCF service with NTLM auth from .NET Core on linux在 Linux 上从 .NET Core 使用 NTLM 身份验证调用 WCF 服务
【发布时间】:2019-05-15 13:13:43
【问题描述】:

我无法通过在 linux 机器(docker 容器)上运行的 .NET Core 成功调用具有 NTLM 身份验证的 WCF 服务。 不过,相同的代码在 Windows 10 上也能完美运行。

我做了什么:

  • 将此添加到ConfigureServices
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
  • 运行apt-get -y install gss-ntlmssp
  • 这是调用服务之前的代码:
var client = new WcfServiceSoapClient();
client.Endpoint.Address = new EndpointAddress(settings.Uri);
client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
client.ClientCredentials.Windows.ClientCredential = new NetworkCredential
{
    Domain = settings.Domain,
    UserName = settings.Username,
    Password = settings.Password
};
var binding = (BasicHttpBinding)client.Endpoint.Binding;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Ntlm;

如前所述,这在 Windows 10 上运行良好。在 Linux 上记录以下错误:

System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM, Negotiate'.
   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass1_0.<CreateGenericTask>b__0(IAsyncResult asyncResult)

问题是:为什么它在 linux 上仍然失败?

【问题讨论】:

  • 服务器使用哪个绑定,你是使用微软wcf web service reference provider生成客户端代理类吗?您是否尝试使用 ChannelFactory 来调用服务? docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/…
  • @AbrahamQian 添加连接服务时,我在 VS2019 中使用了生成的 WSDL 文件,该文件由 WCF 服务的开发人员交给我。我没有使用 ChannelFactory,因为我没有 VS WCF 工具生成的接口。
  • 我设法使用了 ChannelFactory(由于缺少“I”后缀而没有看到界面),但在 Linux 上我遇到了同样的错误:System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM, Negotiate'.
  • 最后我们切换到基本身份验证。 This issue should be fixed in .NET Core 3.

标签: c# linux wcf .net-core ntlm


【解决方案1】:

我发现,如果我们在服务器端的 Windows 身份验证中删除 Negotiate 提供程序,则无论采用哪种调用方式,该项目都可以正常工作。

好像Netframework会自动协商认证方式,Core不能,应该是bug。
如果有什么可以帮助的,请随时告诉我。

【讨论】:

  • 感谢您的回复。我在某处读到删除 Negotiate(甚至先使用 NTLM)可以解决所有问题,但不幸的是,这在我们的案例中不起作用。
  • 就我而言,只有删除 Negotiate 提供程序才能使其工作。看来我们应该确保认证头在双方是相同的。
  • 我询问了另一方(托管 WCF 服务)是否这是他们删除 Negotiate 标头的方式,他们确认了这一点。因此,由于某些未知原因,它仍然无法正常工作。
  • 这对我们也不起作用。我正在尝试找出一种在运行时设置它的方法,这样我就不会更改生成的文件。
【解决方案2】:

在 net core GitHub 上的人的大力帮助下,我遇到了同样的问题并且能够解决它。

本质上,net core 使用底层操作系统来处理 http 调用。以前,在 Linux 上使用 libCurl,但较新的 SocketsHttpHandler 使用 gss,它不支持 ntlm(至少不在“microsoft/dotnet:2.2-aspnetcore-runtime-stretch-slim”图像中)。

要解决此问题,您需要使用 docker 文件在容器中安装一个额外的库。紧接着

来自 microsoft/dotnet:2.2-aspnetcore-runtime-stretch-slim

(或您使用的任何图像)

在下一行添加以下内容:

运行 apt-get update && apt-get install -y --no-install-recommends apt-utils gss-ntlmssp

希望这会有所帮助!

【讨论】:

  • 不,很遗憾没有。我已经尝试过了,但没有任何作用。
  • 我刚刚注意到您设置了 AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false) 并且您还添加了 gss-ntlmssp 包。这似乎很奇怪,因为 GSSAPI 需要 gss-ntlmssp 才能使用 ntlm 身份验证,但是关闭 SocketsHttpHandler 会启用使用 LibCurl 而不是 GSSAPI 的 CurlHandler ...
猜你喜欢
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
相关资源
最近更新 更多