2

我们有一个自托管的 WCF 服务,它通过 HTTP 托管内容,并希望能够支持 Windows / AD 的单点登录。理想情况下,这将支持 IE、Firefox 和 Chrome。

我构建了以下示例服务,该服务通过 HTTP 返回一些纯文本。注意:在这个生产版本中,我们使用 SSL,但我在下面关闭了它,以减少运行示例的挑剔。

我们将 HttpSecurityMode 设置为 TransportCredentialOnly,然后将 ClientCredentialType 设置为 HttpClientCredentialType.Windows,我相信它会使用 Kerberos。

如果我使用“NTLM”而不是“Windows”,它似乎确实可以工作,但我认为不建议使用 NTLM,如果我们的服务前面有一个反向代理,它就会中断。

当我们运行以下代码并在 IE 10 中连接时,我们会得到提示输入我们的 Windows 凭据,但是在输入这些凭据后,我们只会得到一个 HTTP 400,并且我没有在我的“获取”方法中遇到任何断点。理想情况下,我们应该看到“你好,[域\用户]!”的响应。但我们并没有做到那么远。

我们的测试机器(客户端和服务器)都是同一个 Windows 域的一部分。我以本地管理员而不是域管理员的身份运行该服务(如果这很重要)。

我们将不胜感激任何帮助!

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;

namespace WindowsAuthService
{
    [ServiceContract]
    public interface ITestService
    {
        [OperationContract]
        [WebGet(UriTemplate = "{*path}")]
        Stream Get(string path);
    }


    public class TestService : ITestService
    {
        public Stream Get(string path)
        {
            WebOperationContext.Current.OutgoingResponse.Headers.Add(HttpResponseHeader.ContentType, "text/plain");
            if (OperationContext.Current.ServiceSecurityContext == null)
                return new MemoryStream(Encoding.ASCII.GetBytes(String.Format("Hello, {0}!", "Anonymous Stranger")));
            else
                return new MemoryStream(Encoding.ASCII.GetBytes(String.Format("Hello, {0}!", OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name)));
        }
    }

    class Program
    {
        private const string URL = "http://mymachine.mydomain:7777";
        static void Main(string[] args)
        {
            WebServiceHost serviceHost = new WebServiceHost(new TestService());
            foreach (IServiceBehavior attr in serviceHost.Description.Behaviors)
            {
                if (attr is ServiceBehaviorAttribute)
                {
                    ServiceBehaviorAttribute serviceAttr = (ServiceBehaviorAttribute)attr;
                    serviceAttr.InstanceContextMode = InstanceContextMode.Single;
                    serviceAttr.ConcurrencyMode = ConcurrencyMode.Multiple;
                }
            }
            WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            ServiceEndpoint serviceEndpoint = serviceHost.AddServiceEndpoint(typeof (ITestService), binding, URL);
            serviceEndpoint.Behaviors.Add(new WebHttpBehavior());
            Console.WriteLine("Service Listening @ " + URL);
            serviceHost.Open();
            Console.WriteLine("[ Press Enter to Quit ]");
            Console.ReadLine();
        }
    }
}
4

1 回答 1

1

你有工作代码。我猜你有一个代理。如果是,在 IE 10 中,转到菜单工具 > Internet 选项 > 连接(选项卡)> LAN 设置。在对话框中,选中绕过代理服务器以获取本地地址。

此外,您可以转到安全选项卡 > 本地 Intranet > 单击站点按钮并选择自动检测本地 Intranet - 不会提示您输入凭据 - IE 10 将发送登录用户的凭据。

于 2013-05-30T16:32:19.373 回答