我如何确保我的Windows模拟级别有效?
作者:互联网
我正在处理一个令人讨厌的问题,我已经准备好把头发扯下来.我有一个使用Microsoft的HttpListener类侦听Web请求的C#控制台应用程序.这个想法是控制台应用程序作为UserAccountA(低特权)在后台运行. UserAccountB(管理员等)出现,通过侦听器访问网页,并假冒其身份. IIS或WCF会执行相同的操作.我相信我已经在Windows 7上运行了,但是现在我在Windows 8.1上运行,并且再次失败.也许我从来没有开始过,或者这是一个新的转折.
如果我通过Visual Studio运行该程序,则可以使用Internet Explorer 11访问它.由于某种原因,它要求我输入本地凭据.我假设这与IE11的开箱即用行为有关.一旦输入,它就会接受.我的代码是这样开始的:
protected virtual void Listen(object o)
{
HttpListener h = (HttpListener)o;
while (h.IsListening && (this.Disposed == false))
{
IAsyncResult Result = null;
Result = h.BeginGetContext(new AsyncCallback(this.ListenerCallback), h);
Result.AsyncWaitHandle.WaitOne();
}
}
并且像这样(缩写)被拾取:
protected virtual void ListenerCallback(IAsyncResult Result)
{
HttpListener h = (HttpListener)Result.AsyncState;
HttpListenerContext context = null;
System.Security.Principal.WindowsIdentity identity = null;
context = h.EndGetContext(Result);
identity = (System.Security.Principal.WindowsIdentity)context.User.Identity;
using (System.Security.Principal.WindowsImpersonationContext wic = identity.Impersonate())
{
//method call to process request, under impersonation
}
}
当使用两个不同的帐户(一个用于托管,一个用于访问)时,我已经遍历了此代码.我已经使用以下语句进行了验证:
system.security.principal.windowsidentity.getcurrent().name
当前身份确实在过渡.侦听器配置为从NTLM AuthenticationScheme启动.
我想复杂的部分是在模拟过程中调用的方法.我们正在做一些抽象,但是让我只指出失败的部分.在这种情况下,我们使用SSPI连接到SQL Server-因此,模拟的全部要点是获取客户端的现有登录并将它们优雅地导入SQL Server.同样,现在,这都在一台计算机上本地化.它甚至不在活动目录域中.一切都是本地的,带有本地帐户.它是这样开始的:
System.Data.Common.DbProviderFactory fact = null;
if (UseSql())
{
fact = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient");
}
没什么大不了.我们会在另一个项目中不断使用提供程序工厂,而不会出现任何问题(但这只是常规的WPF应用程序,不像这样).在这之后,我们将使用SSPI属性设置SQL登录字符串.但是,我们甚至还没有走得那么远.这是失败的确切位置,并显示以下消息:
A first chance exception of type ‘System.IO.FileLoadException’
occurred in mscorlib.dllAdditional information: Could not load file or assembly
‘System.Data.OracleClient, Version=4.0.0.0, Culture=neutral,
> PublicKeyToken=b77a5c561934e089′ or one of its dependencies. Either a
required impersonation level was not provided, or the provided
impersonation level is invalid. (Exception from HRESULT: 0x80070542)
http://i854.photobucket.com/albums/ab103/srVincentVega/error7_zpsmb1xqrp0.png
我们根本没有使用Oracle,我假设这只是它开始尝试打开DbProviderFactory时的第一件事.对我来说,关键是模仿级别的事情.在此特定实验中,两个帐户(A和B)都是本地管理员.我已通过本地安全策略确保他们可以在登录后模拟帐户.如果我查看事件日志,该模拟似乎确实有效…
Special privileges assigned to new logon.
Subject: Security ID:
pc1\userA
Account Name: userA
Account Domain: pc1 Logon ID: 0xC4D0F3F
Privileges:
SeSecurityPrivilege
SeTakeOwnershipPrivilege
SeLoadDriverPrivilege
SeBackupPrivilege
SeRestorePrivilege
SeDebugPrivilege
SeSystemEnvironmentPrivilege
SeImpersonatePrivilege
我在这里尝试了很多变化,以至于开始阻碍我自己的分析.我基本上回到正题,不知道如何解决这个问题.有人有任何建议或提示吗?这似乎应该很简单.我不确定为什么会有这么多麻烦.也许我只需要扔掉DbProviderFactory的使用,然后再使用OleDb或其他任何东西即可.但是我还没有确认模拟后可以在运行时加载任何库.也许那是要做的事.但是,我将非常感谢您的帮助.
谢谢,
约翰
最后一件事,这是复制步骤:
在您的计算机上创建一个辅助用户.登录以创建配置文件.注销并照常登录.以该次要用户身份运行Visual Studio(有几种方法可以执行此操作,右键单击VS图标),然后在其中创建具有此框架的C#控制台应用程序:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (HttpListener h = new HttpListener())
{
h.Prefixes.Add("http://+:8090/");
h.AuthenticationSchemes = AuthenticationSchemes.Ntlm;
h.Start();
Console.WriteLine("Running");
HttpListenerContext context = h.GetContext();
System.Security.Principal.WindowsIdentity identity = null;
identity = (System.Security.Principal.WindowsIdentity)context.User.Identity;
using (System.Security.Principal.WindowsImpersonationContext wic = identity.Impersonate())
{
System.Data.Common.DbProviderFactory fact = null;
fact = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient");
}
Console.ReadLine();
h.Stop();
}
}
}
}
调试/运行控制台应用程序.只需调用Internet Explorer(使用您的主帐户,使用普通帐户)并访问该URL(http://machinename:8090).发生异常
http://i854.photobucket.com/albums/ab103/srVincentVega/error8_zpsilkay0bl.png
解决方法:
好吧,我读了一半,并在遇到以下异常时停下来:
A first chance exception of type 'System.IO.FileLoadException' occurred in mscorlib.dll
这里的问题是,您用来运行该服务的帐户在甚至无法执行模拟之前,对加载.Net Framework核心库的访问权限有限.通常,用于托管服务的此类帐户在托管服务的节点上具有管理特权.
另外,要允许模拟,您还需要使用本地安全策略-本地策略-用户权限分配来授予服务帐户这样做的特权:
充当操作系统的一部分
此用户权限允许进程假冒任何用户而无需身份验证.因此,该过程可以访问与该用户相同的本地资源.
身份验证后模拟客户端
将此特权分配给用户,将允许代表该用户运行的程序模拟客户端.
还要注意,如果您使用kerberos而不是NTLM,则需要在AD(Actice目录)中设置SPN和委托目标.
我不知道这是否对您有帮助,但是这些都是我们在进行模拟/委派时遇到的.
哦,是的,如果您执行一跳以上来执行模拟,则必须将模拟级别设置为委托.
标签:httplistener,impersonation,c,visual-studio 来源: https://codeday.me/bug/20191028/1954009.html