WCF服务双重冒充?

我的设置有点复杂,所以让我先说一下。

我们有一个WCF Web服务,它通过几个不同的API从各种来源获取数据,并将该数据返回给客户端。 请求的安全性是通过HTTPS完成的(工作)IIS标准是必须将应用程序池设置为使用基本的IIS网络服务帐户,并且应该使用.net模拟。

我的问题是Web服务应始终在AD进程ID下运行,无论谁调用它,但它还应检查调用者所在的AD组以确定可访问的function。 现在我可以设置我的web.config使用和这种工作使它总是作为Blah运行,但后来我不知道如何模仿/检查调用用户,看看他们也有访问的function。

**编辑:忘了提到调用客户端应该能够传递UN / PASS而不仅仅是它的Windows令牌。 wcf服务应该validation其有效的AD UN和PASS以及轮询它所在的组。

听起来你想要HostingEnvironment.Impersonate

例:

 using (var imp = HostingEnvironment.Impersonate()) { // code now executes in the context of the authenticated user, // rather than the service account } 

这非常有效,不幸的是,这里的标准是不使用应用程序池,因为如果每个团队在每个团队中将密码管理放在web.config中,密码管理对他们来说更容易。

嗯,这似乎是违反直觉的,但我在我的日子里遇到了更糟糕的政策,所以我很难判断。 ;)

正如我在评论中提到的,Impersonate存在重载,允许您冒充任意帐户。 为了做到这一点,你必须获得该用户的Windows身份令牌,这是非平凡的,而且据我所知,你不能100%在托管代码中做。 您必须使用非托管代码,并且您必须知道应用程序中模拟帐户的用户名和密码。 如果你想与网络架构师BTW争论这一点,那么这远比简单地将帐户设置为应用程序池ID安全得多。 对你来说只是一些弹药。

无论如何,这里是我从互联网改编的一些示例代码:

 #region native imports. public const int Logon_LogonTypeInteractive = 2; public const int Logon_ProviderDefault = 0; public const int Duplicate_ImpersonationLevelImpersonate = 2; [DllImport("advapi32.dll")] public static extern bool LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static extern bool RevertToSelf(); [DllImport("kernel32.dll", CharSet=CharSet.Auto)] public static extern bool CloseHandle(IntPtr handle); #endregion native imports. #region elsewhere... public IntPtr GetWindowsTokenForImpersonation(string username, string password, string domain) { IntPtr loginToken = IntPtr.Zero; IntPtr workingToken = IntPtr.Zero; bool success if(!RevertToSelf()) { return IntPtr.Zero; // failed to eliminate any existing impersonations. This block may not be necessary depending on your code } if(!LogonUserA(username, domain, password, Logon_LogonTypeInteractive, Logon_ProviderDefault, ref loginToken)) { return IntPtr.Zero; // failed to log in the user } if(!DuplicateToken(loginToken, Duplicate_ImpersonationLevelImpersonate, ref workingToken) { if(loginToken != IntPtr.Zero) { CloseHandle(loginToken); } return IntPtr.Zero; // failed to get a working impersonation token } CloseHandle(loginToken); return workingToken; // NOTE: You must dispose this token manually using CloseHandle after impersonation is complete. } #endregion elsewhere #region where you want to impersonate var token = GetWindowsTokenForImpersonation(username, password, domain); if(token != IntPtr.Zero) { using(var imp = HostingEnvironment.Impersonate(token)) { // code here executes under impersonation } CloseHandle(token); } #endregion