WCF wsHttpBinding的Windows身份验证有多安全?

时间:2010-05-25 16:54:02

标签: .net windows wcf wcf-binding wcf-security

我已经创建了WCF,并且我使用wsHttpBinding和MTOM作为消息传输,认证为“Windows”。

现在我的服务不是当前的SECURE,它是普通的HTTP,在自定义端口上运行。

WCF的wsHttpBinding的Windows身份验证是否安全?谁能看到密码或通过网络追踪猜测?

环境信息:

  1. 在互联网上托管
  2. 没有Active Directory,它的单一服务器
  3. 使用服务器的管理员用户名和密码从我的办公室连接
  4. 在客户端,配置文件中未提及密码,它是在运行时输入的。它正常工作,因为输入错误的凭据也会返回某种安全异常。
  5. 在自定义端口89上运行.NET 4.0,目前我已经在我的自定义Windows服务的app.config中设置了以下配置,我在安装为本地服务的自定义Windows服务中托管我的WCF。我已经为每种方法启用了模拟。
  6. 这是app.config

      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="metaAndErrors">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="true" />
              <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
              <serviceAuthorization impersonateCallerForAllOperations="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service name="CustomServiceHost.CustomService"
                   behaviorConfiguration="metaAndErrors"
                   >
                <endpoint address="" binding="wsHttpBinding"
                      bindingConfiguration="wsHttpLargeBinding"
                      contract="CustomServiceHost.ICustomService"/>
            <endpoint address="mex" binding="mexHttpBinding"
                      contract="IMetadataExchange" />
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:89/CustomService" />
              </baseAddresses>
            </host>
          </service>
        </services>
        <bindings>
          <wsHttpBinding>
            <binding
              name="wsHttpLargeBinding" messageEncoding="Mtom"
              maxReceivedMessageSize="2147483647">
              <readerQuotas maxArrayLength="512000"/>
            </binding>
          </wsHttpBinding>
        </bindings>
      </system.serviceModel>
    

    以下是在运行时完成的客户端配置,

            WSHttpBinding binding = new WSHttpBinding();
    
            binding.Security.Message.ClientCredentialType 
                = MessageCredentialType.Windows;
            binding.Security.Mode = SecurityMode.Message;
    
            binding.MessageEncoding = WSMessageEncoding.Mtom;
    
            binding.ReaderQuotas.MaxArrayLength = 512000;
    
            CustomServiceClient cc = new CustomServiceClient(
                binding,
                new EndpointAddress(string.Format(
                    "http://{0}:89/CustomService", 
                    host.ServerHost))
                );
    
            cc.ClientCredentials.Windows.AllowedImpersonationLevel 
                = System.Security.Principal.TokenImpersonationLevel.Impersonation; 
            cc.ClientCredentials.Windows.ClientCredential 
                = new NetworkCredential(host.Username, host.Password);
    

    谢谢你, - 阿卡什

2 个答案:

答案 0 :(得分:5)

关于密码的问题:Windows身份验证使用Kerberos或NTLM,两种协议都不以明文形式传输密码。

此信息写在此处: http://msdn.microsoft.com/en-us/library/ff647076.aspx

  

您应该使用集成Windows身份验证而不是基本身份验证,因为它可以避免通过网络传输用户凭据。

这意味着您不需要SSL来保护您的密码,但如果您有其他敏感信息(在您的服务电话中),那么您应该考虑使用加密(例如SSL)。我没试过这个,但它应该让你开始:

http://www.codeproject.com/KB/WCF/WCFSSL.aspx

另一种选择是加密消息(消息安全性而不是传输安全性)。这是另一个可以帮助您入门的链接:

http://msdn.microsoft.com/en-us/library/ms733137.aspx

答案 1 :(得分:3)

首先,我在<binding>下找不到子元素

<security mode="Message">
    <message clientCredentialType="Windows" />
</security>

您应该将其插入web.config(或App.config)。它将对应于客户端使用的当前使用的消息安全模式。

此外有点奇怪我发现你没有在IIS服务器下托管WCF服务。作为本地服务安装的使用自定义Windows服务实际上不是成功解决方案的最佳选择。它是您的最终配置还是计划在IIS下最终托管它?如果它是一个已打开的问题,我可以给你发布一些链接,其中描述了不同主机方式的优缺点。在LocalSystem帐户下运行WCF服务是否有一些重要要求?你能不能简要描述一下WCF服务的作用?我有问题给你建议在​​服务器端做太多限制,这可能使WCF的主要工作变得不可能。另一方面,遵循最小特权prinzip来接收更安全的解决方案。

这还不是最后的答案,只是第一个评论。

更新:您好!现在我有时间结束我的回答。首先,我想确认像Stefan Egli(请参阅另一个答案)我确信,密码不会作为明确的文本发送。我只是不确定Windows身份验证是如何工作的,因为没有Active Directory。可能它适用于本地服务器帐户的NTLM身份验证。这个小问题只有在您使用此NTLM时,您无法确定客户端,您真正使用WCF服务器。在这种情况下,证书的使用非常有用。

斯特凡·埃格利在答案中提出的一种方法是SSL。它不仅可以进行数据加密,还可以使用SSL证书对服务器进行身份验证。如果选择将消息模式更改为TransportWithMessageCredential的方式。

如果您进行远程管理的客户端计算机不是免费的非托管客户端,并且您可以在计算机上安装某些组件,我强烈建议您使用基于证书的身份验证和数据加密(请参阅{{ 3)})并在服务器端和客户端安装相应的证书。这种方式是最安全的,在实施后,您将收到客户端和服务器身份验证和加密。

http://www.codeproject.com/KB/WCF/9StepsWCF.aspx下,您将逐步了解如何在WCF中创建和使用客户端和服务器证书。我只想提一下,可以使用Windows SDK中的MakeCert.exe实用程序不仅可以创建自签名证书,还可以创建小型PKI。这是一个例子:

使用

MakeCert.exe -pe -ss MY -a sha1 -cy authority -len 4096 -e 12/31/2020 -r 
             -n "CN=My Company Root Authority,O=My Company,C=DE" MyCompany.cer

您创建一个“root”“Self-Signed”-Certificate并保存在MY(个人)证书存储区中(关于-sv开关的替代方法,您可以将私钥保存在PVK文件中)。您还将它导出到MyCompany.cer(但没有私钥),以便更容易在Truster Root中的客户端和服务器计算机上安装它。然后,您可以创建另外两个证书:一个用于服务器,另一个用于客户端身份验证,使用根证书对这两个证书进行签名。您可以使用与http://www.codeproject.com/KB/WCF/9StepsWCF.aspx

等证书服务器(证书服务)相同的功能

有关其他示例,请参阅示例http://www.codeproject.com/KB/WCF/wcf_certificates.aspx

其他链接很重要 来自http://blogs.microsoft.co.il/blogs/applisec/archive/2008/04/08/creating-x-509-certificates-using-makecert-exe.aspxhttp://msdn.microsoft.com/en-us/library/cc949011.aspx,“操作方法文章” 和http://msdn.microsoft.com/en-us/library/ff648902.aspx对您有所帮助。 文章http://msdn.microsoft.com/en-us/library/ff650794.aspx如何在客户端代码中制作一些内容(就像您目前所做的那样)。