系统相关
首页 > 系统相关> > 我如何确保我的Windows模拟级别有效?

我如何确保我的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.dll

Additional 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