C# 使用WSDualHttpBinding在WCF服务之间共享windows标识

C# 使用WSDualHttpBinding在WCF服务之间共享windows标识,c#,wcf,windows-authentication,wsdualhttpbinding,C#,Wcf,Windows Authentication,Wsdualhttpbinding,我有两个WCF服务分别托管在IIS7中。第一个服务可以从外部调用,并使用带有windows身份验证的WebHttpBinding。第二个服务仅由第一个服务调用,使用WsDualHttpBinding 调用第一个服务时,我可以从ServiceSecurityContext.Current.WindowsIdentity.name获取用户的windows名称。在第二个服务中,这不起作用,ServiceSecurityContext.Current.WindowsIdentity.Name只是IIS

我有两个WCF服务分别托管在IIS7中。第一个服务可以从外部调用,并使用带有windows身份验证的
WebHttpBinding
。第二个服务仅由第一个服务调用,使用
WsDualHttpBinding

调用第一个服务时,我可以从
ServiceSecurityContext.Current.WindowsIdentity.name
获取用户的windows名称。在第二个服务中,这不起作用,
ServiceSecurityContext.Current.WindowsIdentity.Name
只是
IIS APPPOOL\DefaultAppPool

我将
WsDualHttpBinding
配置为使用windows身份验证,但这没有帮助。以下是服务器端配置:

<wsDualHttpBinding>
  <binding name="internalHttpBinding">
    <security mode="Message">
      <message clientCredentialType="Windows"/>
    </security>
  </binding>
</wsDualHttpBinding>

这是第一个服务中用于与第二个服务建立通信的代码:

private WSDualHttpBinding binding = new WSDualHttpBinding();
private ChannelFactory<IMyService> factory;
public IMyService Contract { get; set; }
public MyServiceCallback Callback { get; set; }

public MyService(Uri uri)
{
    EndpointAddress address = new EndpointAddress(uri);
    Callback = new MyServiceCallback();
    var instanceContext = new InstanceContext(Callback);

    binding.Security.Mode = WSDualHttpSecurityMode.Message;
    binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

    factory = new DuplexChannelFactory<IMyService>(instanceContext, binding, address);
    factory.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
    factory.Credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
    Contract = factory.CreateChannel();

    // Call operations on Contract
}
private WSDualHttpBinding=new WSDualHttpBinding();
私营渠道工厂;
公共IMyService协定{get;set;}
公共MyServiceCallback回调{get;set;}
公共MyService(Uri)
{
EndpointAddress地址=新的EndpointAddress(uri);
Callback=newmyservicecallback();
var instanceContext=newinstancecontext(回调);
binding.Security.Mode=WSDualHttpSecurityMode.Message;
binding.Security.Message.ClientCredentialType=MessageCredentialType.Windows;
factory=新的DuplexChannelFactory(instanceContext、binding、address);
factory.Credentials.Windows.AllowedImpersonationLevel=TokenImpersonationLevel.Impersonation;
factory.Credentials.Windows.ClientCredential=CredentialCache.DefaultNetworkCredentials;
Contract=factory.CreateChannel();
//合同呼叫业务
}

如何配置第一个服务以将用户的身份传递给第二个服务?

这似乎是直通式身份验证的问题。 首先,您需要处于Active Directory环境中。 Kerberos必须用于身份验证,NTLM将不起作用。您可以使用klist检查此项:

也看到 我需要一个解释

这篇文章可能有助于:

这是:

在服务器端启用模拟并且客户端设置了windows凭据之后

ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            client.ClientCredentials.Windows.ClientCredential.UserName = "Test";
            client.ClientCredentials.Windows.ClientCredential.Password = "123456";
我们可以使用下面的代码检索正在运行的Windows帐户

if (ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Impersonation ||
    ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Delegation)
{
    using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
    {
        Console.WriteLine("Impersonating the caller imperatively");
        Console.WriteLine("\t\tThread Identity            :{0}",
    WindowsIdentity.GetCurrent().Name);
        Console.WriteLine("\t\tThread Identity level  :{0}",
             WindowsIdentity.GetCurrent().ImpersonationLevel);
        Console.WriteLine("\t\thToken                     :{0}",
             WindowsIdentity.GetCurrent().Token.ToString());
    }
}
请参考以下示例。



如果有什么我可以帮忙的,请随时告诉我。

谢谢你的建议,但我不想硬编码用户名和密码。我现在使用Kerberos身份验证,正如Rainer Schaak的回答中所建议的那样。