【问题标题】:WCF windows authentication security errorWCF windows 身份验证安全错误
【发布时间】:2009-08-13 04:58:53
【问题描述】:

我有一些代码尝试模拟调用者的 Windows 安全设置,然后连接到另一台机器上的另一个 WCF 服务

WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
using (callerWindowsIdentity.Impersonate())
{
    NetTcpBinding binding = new NetTcpBinding();
    binding.Security.Mode = SecurityMode.Message;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
    EndpointAddress endpoint = new EndpointAddress(new Uri("net.tcp://serverName:9990/TestService1"));
    ChannelFactory<WCFTest.ConsoleHost.IService1> channel = new ChannelFactory<WCFTest.ConsoleHost.IService1>(binding, endpoint);
    WCFTest.ConsoleHost.IService1 service = channel.CreateChannel();
    return service.PrintMessage(msg);
}

但我得到了错误: “调用者未经服务验证” System.ServiceModel .... 由于身份验证失败,无法满足对安全令牌的请求...

我试图模拟的凭据是服务所在框的有效 Windows 凭据。

有什么想法吗?

【问题讨论】:

    标签: c# asp.net wcf


    【解决方案1】:

    为了支持您的方案,您需要了解Protocol TransitionConstrained Delegation 的工作原理。您需要同时配置 Active Directory 和 WCF 服务端点以支持此功能。请注意服务主体名称 (SPN) 的使用。查看以下链接,看看它们是否对您有帮助。本文有一个示例来演示完成这项工作所需的完整端到端配置。

    How To: Impersonate the Original Caller in WCF Calling from a Web Application

    【讨论】:

      【解决方案2】:

      同意 marc_s 这是双跳问题。

      你需要一直通过windows认证,因此:

      • 请求必须在 windows 用户的上下文中提出
      • IIS 必须配置为使用 Windows 身份验证
      • Web.config 必须为 windows 身份验证设置 impersonate = true
      • 必须允许运行应用程序池的用户模拟用户。这是经常出现双跳问题的地方。

      有一个权限叫做“身份验证后模拟客户端”

      http://blogs.technet.com/askperf/archive/2007/10/16/wmi-troubleshooting-impersonation-rights.aspx

      【讨论】:

        【解决方案3】:

        从您的服务冒充到下一个服务是一个棘手的问题,称为“双跳”问题。

        对此我没有最终答案(我通常会通过为需要调用另一个服务的服务使用显式服务帐户来避免它)。

        但是:您绝对应该查看 CodePlex 上的 WCF Security Guidance 并搜索“模拟” - 那里有很多文章解释了模拟原始呼叫者的所有细节以及为什么它很棘手。

        马克

        【讨论】:

          【解决方案4】:

          如果您确定您在两个跃点上都拥有正确的凭据,那么可能 导致问题的下一件事是缺少在端点上设置的 EndpointDnsIdentity。

          DnsEndpointIdentity identity = new DnsEndpointIdentity("localhost"); // localhost is default. Change if your service uses a different value in the service's config.
          Uri uri = new Uri("net.tcp://serverName:9990/TestService1");
          endpoint = new EndpointAddress(uri, identity, new AddressHeaderCollection());
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-16
            • 2010-11-04
            • 1970-01-01
            • 2014-07-28
            • 1970-01-01
            相关资源
            最近更新 更多