1

Process.Kill()从 ASP.NET Web 应用程序使用时,我得到一个带有文本“访问被拒绝”的 Win32Exception 。

搜索网络多次告诉我设置权限。但是,我不太了解 Windows XP 用户系统,不知道如何开始。

在抛出异常时,Thread.CurrentPrincipal.Identity具有以下可见属性:

  1. 身份验证类型 = ""
  2. IsAuthenticated = "假"
  3. 名称 = ""

WindowsIdentity.GetCurrent()显示我以“NAME\ASPNET”的身份登录,但我认为这无关紧要。

我需要做什么?我可以以某种方式让线程以某些 Windows 用户身份登录吗?

4

3 回答 3

2

我认为您的方法正确,“访问被拒绝”的问题是由于 ASP.NET 进程与 ASPNET 用户一起运行,该用户具有有限的权限,这就是您遇到的错误。您可以做的是为您的 Web 应用程序设置 imersnation。您可以通过更改 web.config 或代码来实现。有关模拟的更多信息,您可以在此处阅读

web.comfig 非常简单,您需要在 web.config 的 system.web 部分添加以下行

<identity impersonate="true" userName="domain\user" password="password" />

用户需要在服务器上具有管理员权限

如果您想在下面的代码中执行模拟是如何执行此操作的示例:

...
WindowsImpersonationContext context = ImpersonateUser("domain", "user", "password");
// kill your process
context.Undo();
...

[DllImport("advapi32.dll")]
private static extern bool LogonUser(
    String lpszUsername, String lpszDomain, String lpszPassword,
    int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

[DllImport("advapi32.dll")]
private static extern bool DuplicateToken(
    IntPtr ExistingTokenHandle, int ImpersonationLevel,
    ref IntPtr DuplicateTokenHandle);

[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);


private enum SecurityImpersonationLevel
{
    SecurityAnonymous,
    SecurityIdentification,
    SecurityImpersonation,
    SecurityDelegation
}

private enum LogonTypes
{
    LOGON32_PROVIDER_DEFAULT=0,
    LOGON32_LOGON_INTERACTIVE=2,
    LOGON32_LOGON_NETWORK=3,
    LOGON32_LOGON_BATCH=4,
    LOGON32_LOGON_SERVICE=5,
    LOGON32_LOGON_UNLOCK=7,
    LOGON32_LOGON_NETWORK_CLEARTEXT=8,
    LOGON32_LOGON_NEW_CREDENTIALS=9
}

public static WindowsImpersonationContext ImpersonateUser(string domain, string username, string password)
{
    WindowsImpersonationContext result = null;
    IntPtr existingTokenHandle = IntPtr.Zero;
    IntPtr duplicateTokenHandle = IntPtr.Zero;

    try
    {
        if (LogonUser(username, domain, password,
            (int)LogonTypes.LOGON32_LOGON_NETWORK_CLEARTEXT, (int)LogonTypes.LOGON32_PROVIDER_DEFAULT,
            ref existingTokenHandle))
        {
            if (DuplicateToken(existingTokenHandle,
                (int)SecurityImpersonationLevel.SecurityImpersonation,
                ref duplicateTokenHandle))
            {
                WindowsIdentity newId = new WindowsIdentity(duplicateTokenHandle);
                result = newId.Impersonate();
            }
        }
    }
    finally
    {
        if (existingTokenHandle != IntPtr.Zero)
            CloseHandle(existingTokenHandle);
        if (duplicateTokenHandle != IntPtr.Zero)
            CloseHandle(duplicateTokenHandle);
    }
    return result;
}

希望这会有所帮助,问候

于 2009-11-21T00:11:22.360 回答
1

您需要以具有足够权限的用户身份运行您的 C# 应用程序。

如果您不能信任具有此类权限的 ASP AppPool(您不应该),您需要创建一个单独的服务,该服务在具有足够权限的帐户下运行,并在低权限应用程序和高权限服务之间建立协议,以便与目的进行通信杀死一个进程。

不要在 AppPool 中冒充高权限用户。你必须出示它的密码,这样你就有效地将低权限帐户提升到高权限帐户,通过所有有效的手段,在 AppPool 被破坏的情况下,就像你在高权限下运行 AppPool 并且没有完成任何隔离一样.

于 2009-11-20T22:27:13.647 回答
0

基于 Serge Gubenko 的回答,这里是模拟和杀死进程的代码(他在回答中写了“//杀死你的进程”):

using (WindowsImpersonationContext context = ImpersonateUser("domain", "user", "password"))
    {
        Process[] proc = Process.GetProcessesByName("process name");
        if (proc.Length > 0)
            proc[0].Kill();

        context.Undo();
    }

您仍然需要在他的答案中使用其余代码。请注意,如果您不是域的一部分,只需输入一个空字符串

于 2019-06-24T07:58:55.003 回答