代码之家  ›  专栏  ›  技术社区  ›  Alex Angas Colin

如何编写调用WCF服务并在需要时从Kerberos回退到NTLM的代码?

  •  8
  • Alex Angas Colin  · 技术社区  · 15 年前

    我需要以编程方式调用WCF服务。该服务可以托管在 NTLM或Kerberos身份验证 需要在任何一种情况下工作。也就是说,如果通过Kerberos连接到服务失败,那么它应该退回到NTLM。

    下面是我用于Kerberos auth的代码(如果相关,则该服务托管在sharepoint2010中,并从web部件调用):

    public static SiteMembershipSvc.SiteMembershipServiceClient InitialiseSiteMembershipService(string url)
    {
        var binding = new BasicHttpBinding();
        binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
        url = url.EndsWith("/") ? url + SiteMembershipAddress : url + "/" + SiteMembershipAddress;
        var endpoint = new EndpointAddress(url);
        var proxy = new SiteMembershipSvc.SiteMembershipServiceClient(binding, endpoint);
        proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
        return proxy;
    }
    

    在NTLM环境中运行时调用代理上的方法会出现错误:

    HTTP请求未经授权 “协商”。身份验证标头 从服务器接收的是“NTLM”。

    注意:URL可能位于另一台服务器上的另一个web应用程序中。我无法检查web部件的web应用在什么身份验证下运行,并假设它与WCF服务所在的位置相同。

    更新:

    我试过用 proxy.Open()

    7 回复  |  直到 15 年前
        1
  •  1
  •   Spence    15 年前

    这有点像弧线球,但为什么要回到NTLM呢。我在activedirectory和WCF中遇到了很大的安全问题,所有这些都与服务主体名称(spn)有关。

    setspn -A HTTP\machinename domain\service_account
    

    然后,这将允许Kerberos在域内与您的服务共享客户端凭据。

    请做一些阅读,因为您可能会破坏kerberos为任何其他服务运行在同一个框取决于您的设置。

        2
  •  1
  •   Les    10 年前

    您能使用BasicHttpBinding以外的东西吗(比如WsHttpBinding)?根据 this 第三条,BasicHttpBinding是绑定对象的一个例外,因为它不会自动协商。这就是allowNTLM没有效果的原因。

        3
  •  0
  •   JumpingJezza    15 年前

    here 通过创建一个动态端点解决了这个问题,如下所示:

    public static SiteMembershipSvc.SiteMembershipServiceClient InitialiseSiteMembershipService(string url)
    {
        //create endpoint
        EndpointAddress ep = new EndpointAddress(new Uri(string), EndpointIdentity.CreateUpnIdentity("MyDomain\WCFRunAsUser"));
        //create proxy with new endpoint
        SiteMembershipSvc.SiteMembershipServiceClient service = new SiteMembershipSvc.SiteMembershipServiceClient("wsHttp", ep);
        //allow client to impersonate user
        service.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
        //return our shiny new service
        return service;
    }
    

    我是作为特定的activedirectory用户运行WCF服务的,而不是默认的网络服务。

        4
  •  0
  •   Alex Peck    15 年前

    尝试设置:

    proxy.ClientCredentials.Windows.AllowNTLM = true;

    根据 this ,AllowNTLM现在已经过时了-我不确定正确的替代方法是什么。

        5
  •  0
  •   Cosmin Onea    15 年前

    如果您知道服务器使用的是什么协议,您可以将应用程序配置为使用全名或ip。

        7
  •  0
  •   Alex Angas Colin    15 年前

    推荐文章