【问题标题】:Error connecting to WCF service from its hosting server从其托管服务器连接到 WCF 服务时出错
【发布时间】:2012-02-21 06:22:57
【问题描述】:

这可能很愚蠢/不可能。但是,我想要实现的目标如下:

  • 我有一个在 Windows Server 2008 上的 IIS 7 中托管 WCF Web 服务的 VM
  • 我正在使用基本的http绑定
  • 客户端代码在其他机器上完美运行
  • 此服务器虚拟机还需要执行批处理,因此我需要在其上使用客户端访问这些 WCF 服务
  • 在托管 WCF 服务的实际机器上运行时,我得到...

    System.ServiceModel.Security.MessageSecurityException:HTTP 请求未经客户端身份验证方案“Ntlm”授权。从服务器收到的身份验证标头是“协商,NTLM”。 ---> System.Net.WebException:远程服务器返回错误:(401)未经授权。 在 System.Net.HttpWebRequest.GetResponse() 在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度超时) --- 内部异常堆栈跟踪结束 ---

    服务器堆栈跟踪: 在 System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest 请求,HttpWebResponse 响应,WebException responseException,HttpChannelFactory 工厂) 在 System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest 请求,HttpWebResponse 响应,HttpChannelFactory 工厂,WebException responseException) 在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度超时) 在 System.ServiceModel.Channels.RequestChannel.Request(消息消息,TimeSpan 超时) 在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息消息,TimeSpan 超时) 在 System.ServiceModel.Channels.ServiceChannel.Call(字符串操作,布尔单向,ProxyOperationRuntime 操作,Object[] 输入,Object[] 输出,TimeSpan 超时) 在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime 操作) 在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)

    在 [0] 处重新抛出异常: 在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg) 在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 类型)

我想知道的是我正在尝试的事情是否真的可行 - 我看不出为什么我不能从主机连接到服务,但具体情况可能会阻止我 - 如果是的话,什么我需要对我的设置进行更改才能实现它?

相关dll设置绑定如下...

    BasicHttpBinding binding = new BasicHttpBinding();

    binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
    binding.TransferMode = TransferMode.Buffered;
    binding.MaxBufferPoolSize = int.MaxValue;
    binding.MaxReceivedMessageSize = int.MaxValue;
    binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
    binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
    binding.OpenTimeout = openTimeout;
    binding.SendTimeout = sendTimeout;
    binding.ReceiveTimeout = receiveTimeout;
    binding.CloseTimeout = closeTimeout;

    return binding;

cscript 认证的输出是...

NTAuthenticationProviders       : (STRING) "Negotiate,NTLM"

该服务设置为要求连接用户所属的网络组的成员身份 (PrincipalPermission)。

如下 cmets 所示,我查看了安全事件日志,发现当用户(网络帐户)作为客户端连接到主机上的 WCF 服务时,有一个条目抱怨该帐户无法登录- 传递了一个空 SID。

An account failed to log on.

Subject:
    Security ID:        NULL SID
    Account Name:       -
    Account Domain:     -
    Logon ID:       0x0

Logon Type:         3

Account For Which Logon Failed:
    Security ID:        NULL SID
    Account Name:       *<network account>*
    Account Domain:     *<account domain>*

Failure Information:
    Failure Reason:     An Error occured during Logon.
    Status:         0xc000006d
    Sub Status:     0x0

问题是,为什么会这样?

【问题讨论】:

  • 客户端没有配置 - 它是一个 DLL - 所以设置是以编程方式执行的。 binding.Security.Transport.ClientCredentialType 行对 NTLM 执行设置。我相信这个问题是由于我在托管服务的服务器上运行客户端代码,因为这在其他地方工作。我只是不知道要改变什么。
  • 我还尝试将客户端更改为使用 Windows 而不是 NTLM。获得类似的回击,但在错误消息中将 Ntlm 与 Negotiate 交换。我确定这是一个“仅在服务器上”的问题,可能是 WCF,可能是 IIS 配置等。
  • 我现在已经查看了相关服务器上的安全事件日志,当 WCF 服务作为服务主机上的客户端连接时,它似乎正在接收该帐户的 Null SID。问题是,为什么 SID 为空?

标签: c# wcf authentication ntlm


【解决方案1】:

post 上的方法 1 可以解决问题...

DisableStrictNameChecking = 1 BackConnectionHostNames = 在我的例子中,服务器的完整域名限定别名

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多