1

我们正在开发许多托管在 IIS 中的 WCF 服务。(在 Windows Server 2003 SP2 上运行的 IIS 6.0)。这些服务是为 REST 设置的。对于环境(DEV、CERT、PROD),我们通常在每个 IIS 服务器上有许多服务。每个服务都有自己的登录帐户,通过应用程序池分配。

这很好用,但是如果我们在虚拟目录上启用 Windows 身份验证(以允许用户上下文传递,而不是模拟或委托),我们会在特定情况下遇到安全错误。如果我们使用 ServiceEndpoint 连接到 C# 代码中的服务,它可以工作,但是当我们通过浏览器或非 Wcf 代码(例如 HttpWebRequest、java 等)连接到服务时,我们会收到安全错误。

如果我将 IIS 中的身份验证从协商、NTLM 更改为 NTLM,那么它就可以工作。真正发生的事情是我们正在禁用 Kerberos,并且由于这些服务与网络中的其他服务器通信,我们开始遇到服务无法连接到远程服务器(通常是 SQL Server)的其他问题。

现在这是奇怪的部分,如果我们给机器一个 DNS 别名(CNAME 记录)并将 URL 与它的别名一起使用。例如

http://dnsalias/service/myservice.svc/foo WORKS!
but
http://machinename/service/myservice.svc/foo  FAILS :(

我们不能为所有这些机器提供 DNS 别名(这一直是我们目前的解决方案),因为我们开始广泛使用虚拟机并让它们上下运转。所以我们只有机器名称,我们不想在机器启动时开始编写 DNS 别名脚本。

现在我知道了 SPN 问题,但是,由于我们在同一个网站(通常是默认网站)上托管了多个服务,我们只能为每个服务器/帐户创建 1 个服务主体名称。由于我们为每台服务器托管多个服务,每个服务都映射到自己的帐户,因此这不是解决方案。

setspn -a HTTP//WCFServer.domain.com customDomainAccount

另一个问题,我们没有在配置文件中定义端点,只在代码中,这里是获取 REST 绑定的代码。

protected internal static Binding GetWebHttpBinding()
        {
            // Create a new binding with Authentication enabled
            var binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);

            // Set defaults
            SetTimeouts(binding);
            SetReaderQuotas(binding.ReaderQuotas);
            binding.MaxReceivedMessageSize = MaxReceivedMessageSize;
            binding.MaxBufferSize = 65536;

            // Set the Credential type to Windows to allow single sign-on
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

            // Need Streamed Response since Transport security does not allow streamed requests
            binding.TransferMode = TransferMode.StreamedResponse;

            return binding;
        }
4

3 回答 3

1

好的,很久以后,我回来了答案。对于所描述的环境,唯一的答案是使用 NTLM 身份验证。这已通过致电 Microsoft 支持部门得到确认。

于 2011-09-02T16:33:42.830 回答
0

我了解到机器名称已经是DNS 条目。机器的原始名称/或查找实际上是它的 IP 地址。因此,当您在无效的 url 中声明“machinename”时,那不是已经是 DNS 条目了吗?如果您 p​​ing 'machinename' 显示响应 ping 的 IP 是什么?那应该是机器的IP。

对我来说,听起来您正在为 DNS 查找创建 DNS 查找。你能澄清一下吗?

我可以确认,一旦我在域上对我正在使用的 WCF 服务或站点的 IP 进行 DNS 查找,我就会发现魔法发生了,所以我知道你来自哪里。

我不知道您的客户端代码是什么样的,但请查看以下链接以匹配。在调用 RESTful 服务之前,您必须建立网络凭据。如果你这样做,它是否解决了必须禁用 kerberos 的另一个问题?

于 2010-08-06T17:11:07.393 回答
0

我也遇到了类似的“安全错误”,集成 Windows 身份验证和 WebHttpBinding 试图利用WebHttpSecurityMode.TransportCredentialOnly .. 但需要 SSL,所以我能够在配置HttpClientCredentialType.Windows的同时坚持使用WebHttpSecurityMode.Transport

于 2013-02-12T04:59:55.193 回答