使用 WSDualHttpBinding 在 WCF 服务之间共享 windows 身份
Share windows identity between WCF services with WSDualHttpBinding
我在 IIS 7 中分别托管了两个 WCF 服务。第一个服务可从外部调用,并使用 WebHttpBinding
和 windows 身份验证。第二个服务仅由第一个服务调用,使用 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
}
如何配置第一个服务以将用户身份传递给第二个服务?
这似乎是传递身份验证的问题。
首先,您需要处于 Active Directory 环境中。
必须使用 Kerberos 进行身份验证,NTLM 将不起作用。您可以使用 klist 来检查:
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/klist
可能这篇 SO 文章可以提供帮助:
服务器端启用模拟且客户端已设置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());
}
}
请参考下面的例子
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/impersonating-the-client
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/delegation-and-impersonation-with-wcf
如果有什么我可以帮忙的,请随时告诉我。
我在 IIS 7 中分别托管了两个 WCF 服务。第一个服务可从外部调用,并使用 WebHttpBinding
和 windows 身份验证。第二个服务仅由第一个服务调用,使用 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
}
如何配置第一个服务以将用户身份传递给第二个服务?
这似乎是传递身份验证的问题。 首先,您需要处于 Active Directory 环境中。 必须使用 Kerberos 进行身份验证,NTLM 将不起作用。您可以使用 klist 来检查: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/klist
可能这篇 SO 文章可以提供帮助:
服务器端启用模拟且客户端已设置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());
}
}
请参考下面的例子
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/impersonating-the-client
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/delegation-and-impersonation-with-wcf
如果有什么我可以帮忙的,请随时告诉我。