我有一个ASP.NET MVC WebApplication,托管在server-frontend
,它是server-wcf
中托管的WCF应用程序的客户端,两者都在同一个网络/域中。两台服务器都是运行IIS 8的Windows Server 2012。
我在两个项目中启用了Windows身份验证并禁用了匿名(csproj)。
如果我在我的WebApp中的控制器中调用this.User.Identity.Name
,它会正确地提供登录的用户(例如mydomain \ alisson)。
两个项目都在IIS中配置了Windows身份验证,而WebApp特别启用了ASP.NET模拟。两者都禁用表单,基本和匿名。两个池都使用NetworkService
。
我的WCF项目负责连接到SQL Server,并且它正常工作,因为我在我的数据库中授予了机器本身的权限(例如server-wcf$
),这正是我所期望的。
现在我正试图从我的WebApp中调用WCF方法,如下所示:
var binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = 10485760;
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
var endPoint = new EndpointAddress(address);
var channelFactory = new ChannelFactory<IMyService>(binding, endPoint);
var client = channelFactory.CreateChannel();
client.GetUser();
并且我的WCF服务中的GetUser()
声明如下:
public GetUser()
{
return ServiceSecurityContext.Current.WindowsIdentity.Name;
}
返回domain\server-frontend
而不是domain\alisson
。
我想让它在WCF中获取用户,但保持WCF连接数据库的方式(server-wcf)。
我的WebApp web.config具有以下内容:
<identity impersonate="true" />
<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>
而WCF在web.config serviceModel中包含以下内容:
<bindings>
<basicHttpBinding>
<binding name="AutomatizacaoBinding" maxReceivedMessageSize="10485760">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
有可能实现这个目标吗?
答案 0 :(得分:0)
您应该使用OperationContext
代替:
return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;
注意:如果未启用集成安全性,ServiceSecurityContext
将为空。
希望它有所帮助。
答案 1 :(得分:0)
很可能但不那么容易。
您可能只能获取调用者的名称,但不能重建他们的身份。永远,在重建身份时,必须在机器之间使用Negotiate / Kerberos Security for more than one jump。
基本上真的很无聊,因为并不总是有可用于测试的Active Directory服务器(我必须在我所在的生产环境中创建测试帐户)。 Neg / Kerberos是我大部分时间都使用的老技术,尽管有一些关于SPN和CNAME的警告(不要使用CNAMES,使用A记录)。
另一种选择是使用像ADFS这样的新技术来传递某种叫做联邦的大型声明cookie,但这完全取决于你的生产环境是什么样的。
一旦设置了这个,一个或另一个,如果你希望WCF继续自己进行调用,只需保留你的代码并且不要设置任何隐式模拟。如果你在大多数情况下在wcf请求中逛了,你仍然可以获得身份。
如果您想实际模拟,请打开impersonation scope。只要重复一下这个例子,除非先设置Kerberos或adfs,否则以下内容永远不会有效。
using System.Security.Principal;
using(WindowsIdentity.GetCurrent().Impersonate())
{
//your code goes here, executed as domain\alisson
}