一些客户端需要能够使用基本身份验证连接到我们的 WCF SOAP 服务,而其他客户端需要使用 Windows 身份验证。我们通常在 IIS 中托管我们的服务,尽管我们确实提供了一个不太发达的 Windows 服务托管选项。
据我了解,不可能将一个端点配置为同时支持基本身份验证和 Windows 身份验证。所以我们每个服务有两个端点。
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicBinding" contract="SomeContract" bindingNamespace="http://www.somewhere.com/Something" />
<endpoint address="win" binding="basicHttpBinding" bindingConfiguration="WindowsBinding" contract="SomeContract" bindingNamespace="http://www.somewhere.com/Something" />
...
<bindings>
<basicHttpBinding>
<binding name="BasicBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="WindowsBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
它们位于 IIS 中的同一个 Web 应用程序中。该 Web 应用程序同时启用了基本和 Windows 身份验证(否则上述绑定之一将不起作用)。
当客户端使用 Windows 身份验证的端点(在 URL 的末尾带有“win”)时,这通常可以正常工作。当初始请求不包含任何身份验证信息时,客户端和 IIS 之间会进行协商,他们选择 Windows 身份验证,一切顺利。
当客户端使用经过基本身份验证的端点(URL 末尾没有“win”)时,如果它们包含 Authorization HTTP 标头以及其中的正确编码凭据,则此方法有效。但是,如果它们在初始请求中不包含任何身份验证信息,则协商最终会选择 Windows 身份验证。这使请求通过了 IIS 安全性,但 WCF 随后拒绝了该请求,因为它会发送到经过基本身份验证的终结点。
我对谈判中到底发生了什么感到很模糊。但在我看来,IIS 提供了为 Web 应用程序启用的所有身份验证方法(即 Basic 和 Windows),即使请求的特定 WCF 端点 URL 仅支持 Basic。
我想知道我们是否可以在 IIS 中做任何事情来使协商得出正确的答案:也就是说,如果请求是针对 Basic 身份验证的端点,请告诉客户端使用 Basic。当然,当请求到达 Windows 身份验证的端点时,我们仍然希望协商最终选择 Windows。
如果没有,那么您认为我们是否会更好地专注于我们的 Windows 服务托管版本的服务?还是会以某种方式有类似的问题?
最后一点:我们确实将 Basic 与 HTTP 一起用于一些内部用途,但我们知道这是一个不安全的组合。所以我们通常会打开 HTTPS 用于生产用途;为了简单起见,我把它留在这里了。