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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2906685/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:31:36  来源:igfitidea点击:

How secure is WCF wsHttpBinding's Windows authentication?

.netwindowswcfwcf-bindingwcf-security

提问by Akash Kava

I have created WCF and I have used wsHttpBinding and MTOM as message transport with authentcation as "Windows".

我创建了 WCF,并使用 wsHttpBinding 和 MTOM 作为消息传输,身份验证为“Windows”。

Now my service is not current SECURE, its plain HTTP, running on custom port.

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

Is Windows Authentication of WCF's wsHttpBinding secure? can anyone see the password or guess through network trace?

WCF 的 wsHttpBinding 的 Windows 身份验证安全吗?任何人都可以通过网络跟踪看到密码或猜测吗?

Environment Information:

环境信息:

  1. Hosted on Internet
  2. No Active Directory, its single server
  3. Connecting from my office with server's admin username and password
  4. On the client side, Password is not mentioned in config file, it is entered at runtime. It works correctly becausing entering wrong credentials returns some sort of security exception as well.
  5. Running .NET 4.0, on custom port 89, currently I have set following configuration in app.config of my custom windows service, I am hosting my WCF inside custom windows service installed as Local Service. I have enabled impersonation on each method.
  1. 托管在互联网上
  2. 没有活动目录,它的单一服务器
  3. 使用服务器的管理员用户名和密码从我的办公室连接
  4. 在客户端,配置文件中没有提到密码,它是在运行时输入的。它可以正常工作,因为输入错误的凭据也会返回某种安全异常。
  5. 在自定义端口 89 上运行 .NET 4.0,目前我在自定义 Windows 服务的 app.config 中设置了以下配置,我将 WCF 托管在安装为本地服务的自定义 Windows 服务中。我已经启用了每种方法的模拟。

Here is the app.config

这是 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>

Following is client configuration done at runtime,

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

        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);

Thank you, - Akash

谢谢你 - 阿卡什

回答by Stefan Egli

Regarding your question about the passwords: Windows Authentication either uses Kerberos or NTLM and neither protocol transfers passwords in clear text.

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

This information is written here: http://msdn.microsoft.com/en-us/library/ff647076.aspx

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

You should use Integrated Windows authentication instead of basic authentication because it avoids transmitting user credentials over the network.

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

This means you do not need SSL to protect your passwords, but if you have other information that is sensitive (in your service calls) then you should consider to use encryption (e.g. SSL). I did not try this, but it should get you started:

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

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

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

Another option would be to encrypt the messages (message security instead of transport security). Here is another link that should get you started:

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

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

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

回答by Oleg

First of all I could not find under <binding>a child element

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

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

You should insert it in web.config(or App.config). It will corresponds to the currently used message security mode used on the client side.

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

Moreover a little strange I find that you don't host the WCF service under IIS server. Usage custom windows service installed as Local Service is really not the best choice for a sucure solution. Is it your final configuaration or do you plan to host it at the end under IIS? If it is an opened question I could post you some links where advantages and disadvantages of different hosting ways are described. Are there some important requirements to have WCF service running under LocalSystemaccount? Could you shortly describe what the WCF service do? I have problem to give you recommendation to makes too much restriction on the server side which could make the main work of WCF impossible. On the other side to have follow least privilege prinzip to recieve more secure solution.

此外,我发现您没有在 IIS 服务器下托管 WCF 服务,这有点奇怪。使用安装为本地服务的自定义 Windows 服务确实不是完美解决方案的最佳选择。这是您的最终配置还是您计划在 IIS 下托管它?如果这是一个悬而未决的问题,我可以向您发布一些链接,其中描述了不同托管方式的优缺点。在LocalSystem帐户下运行 WCF 服务是否有一些重要要求?您能否简要介绍一下 WCF 服务的作用?我有问题建议您在服务器端做出太多限制,这可能会使 WCF 的主要工作无法进行。另一方面遵循最小权限原则以获得更安全的解决方案。

It is not yet the final answer, only the first remarks.

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

UPDATED: Hello! Now I have time to end my answer. First of all I want confirm that like Stefan Egli (see another answer) I am sure, that passwords will not send as a clear texts. I am only not sure how exactly Windows authentication works it you have no Active Directory. Probably it works as NTLM authentication with the local server accounts. The small problem is only if you use this NTLM you could not be sure on the client side, that you works really with your WCF server. In such cases the usage of certificate are very helpful.

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

One way, which suggested also Stefan Egli in his answer, is SSL. It not only makes data encryption, but also authenticate server with the SSL certificate. If you choose the way you should change to message mode to TransportWithMessageCredential.

在他的回答中也建议 Stefan Egli 的一种方法是 SSL。它不仅可以对数据进行加密,还可以使用 SSL 证书对服务器进行身份验证。如果您选择应该将消息模式更改为 TransportWithMessageCredential 的方式。

If the client computer from which you made a remote administration is not a free unmanaged client and you are able to install some components on the machine I'll strongly recommend you to use certificate based authentication and encryption of data (see http://www.codeproject.com/KB/WCF/9StepsWCF.aspx) and install corresponding certificates on both server and client sides. This way is the most secure and after the implementation you will receive both client and server authentication and encryption.

如果您进行远程管理的客户端计算机不是免费的非托管客户端,并且您能够在机器上安装一些组件,我强烈建议您使用基于证书的身份验证和数据加密(请参阅http://www .codeproject.com/KB/WCF/9StepsWCF.aspx)并在服务器端和客户端安装相应的证书。这种方式是最安全的,实施后您将同时收到客户端和服务器的身份验证和加密。

Under http://www.codeproject.com/KB/WCF/9StepsWCF.aspxyou will find step by step information how to create and use client and server certificates in WCF. I want only to mention, that one can use MakeCert.exe utility from Windows SDK not only to create a self-signed certificates, but also to create a small PKI. Here is an example:

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

With

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

you create a "root" "Self-Signed"-Certificate and save if in MY (personal) certificate store (alternative with respect of -sv switch you can save the private key in a PVK file). You export it also to MyCompany.cer (but without a private key) to make it easier to install it on the client and server computers in Truster Root. Then you can create two other certificates: one for the server and other for a client authentication using root certificate to sign this two certificates. You can do absolutely the same things as in case of having Certificate Server (certificate services) like http://www.codeproject.com/KB/WCF/wcf_certificates.aspx

您创建一个“根”“自签名”证书并保存在我的(个人)证书存储中(替代 -sv 开关,您可以将私钥保存在 PVK 文件中)。您还可以将其导出到 MyCompany.cer(但没有私钥),以便更轻松地将其安装在 Truster Root 中的客户端和服务器计算机上。然后您可以创建另外两个证书:一个用于服务器,另一个用于使用根证书签署这两个证书的客户端身份验证。您可以做与拥有证书服务器(证书服务)(如http://www.codeproject.com/KB/WCF/wcf_certificates.aspx)完全相同的事情

See for example http://blogs.microsoft.co.il/blogs/applisec/archive/2008/04/08/creating-x-509-certificates-using-makecert-exe.aspxfor additional examples.

有关其他示例,请参见例如http://blogs.microsoft.co.il/blogs/applisec/archive/2008/04/08/creating-x-509-certificates-using-makecert-exe.aspx

Other links are important http://msdn.microsoft.com/en-us/library/cc949011.aspx, "How-to Articles" from http://msdn.microsoft.com/en-us/library/ff648902.aspxand http://msdn.microsoft.com/en-us/library/ff650794.aspxcan be helpful for you. The article http://msdn.microsoft.com/en-us/library/ms789011.aspxhow to make some things in client code (like you do currently).

其他链接很重要 http://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可以为您提供帮助。文章http://msdn.microsoft.com/en-us/library/ms789011.aspx如何在客户端代码中做一些事情(就像你目前所做的那样)。