Создание процесса, который выполняется в контексте олицетворенного пользователя в Microsoft ASP.NET
В этой статье описывается, как создать процесс, который выполняется в контексте олицетворенного пользователя.
Исходная версия продукта: ASP.NET
Исходный номер базы знаний: 889251
Введение
В этой пошаговой статье описывается, как создать процесс, который выполняется в контексте олицетворенного пользователя на ASP.NET страницах. Чтобы создать процесс, который выполняется в контексте олицетворенного пользователя, нельзя использовать System.Diagnostics.Process.Start
метод . Это связано с тем, что в ASP.NET олицетворение выполняется на уровне потока, а не на уровне процесса. Таким образом, любой процесс, который вы создаете из ASP.NET, будет выполняться в контексте рабочего процесса ASP.NET, а не в олицетворенного контекста.
Описание метода
Чтобы обойти эту проблему, необходимо выполнить вызов платформы (P/Invoke) к следующим API Win32:
Функция
CreateProcessAsUser
создает процесс под удостоверением маркера безопасности, указанного в одном из параметров. Однако для вызова функции требуетсяCreateProcessAsUser
первичный маркер. Поэтому необходимо преобразовать олицетворенный маркер в первичный маркер.Функция
DuplicateTokenEx
преобразует олицетворенный токен в первичный маркер.CreateProcessAsUser
Вызов функции использует этот первичный маркер.
Примечание.
Чтобы вызов CreateProcessAsUser
функции работал, пользователю, олицетворяемому пользователю должны быть назначены следующие права безопасности:
- На компьютере под управлением Windows назначьте право пользователя Заменить маркер уровня процесса и Право пользователя Увеличить квоты для олицетворенного пользователя.
- На компьютере под управлением Windows Server или Windows XP назначьте право пользователя Заменить маркер уровня процесса олицетворенным пользователем.
Шаги по порождению процесса
Корпорация Майкрософт предоставляет примеры программирования только в целях демонстрации без явной или подразумеваемой гарантии. Данное положение включает, но не ограничивается этим, подразумеваемые гарантии товарной пригодности или соответствия отдельной задаче. Эта статья предполагает, что пользователь знаком с представленным языком программирования и средствами, используемыми для создания и отладки процедур. Специалисты технической поддержки Майкрософт могут пояснить работу той или иной процедуры, но модификация примеров и их адаптация к задачам разработчика не предусмотрена. Чтобы создать процесс, который выполняется в контексте олицетворенного пользователя, выполните следующие действия:
В Visual Studio .NET создайте новое ASP.NET веб-приложение Visual C# и присвойте приложению имя Q889251.
Откройте файл WebForm1.aspx в представлении кода.
В файле WebForm1.aspx добавьте следующие инструкции в блок кода using.
using System.Runtime.InteropServices; using System.Security.Principal;
Найдите строку кода, похожую на следующую строку кода.
public class WebForm1 : System.Web.UI.Page
После строки кода, указанной на шаге 4, добавьте следующий код.
[StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public int cb; public String lpReserved; public String lpDesktop; public String lpTitle; public uint dwX; public uint dwY; public uint dwXSize; public uint dwYSize; public uint dwXCountChars; public uint dwYCountChars; public uint dwFillAttribute; public uint dwFlags; public short wShowWindow; public short cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public uint dwProcessId; public uint dwThreadId; } [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int Length; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; } [DllImport("kernel32.dll", EntryPoint="CloseHandle", SetLastError=true, CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)] public extern static bool CloseHandle(IntPtr handle); [DllImport("advapi32.dll", EntryPoint="CreateProcessAsUser", SetLastError=true, CharSet=CharSet.Ansi, CallingConvention=CallingConvention.StdCall)] public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("advapi32.dll", EntryPoint="DuplicateTokenEx")] public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
В Обозреватель решений щелкните правой кнопкой мыши WebForm1.aspx и выберите команду Открыть. Веб-форма откроется в режиме конструктора.
В меню Вид выберите пункт HTML-источник.
Замените весь существующий код в окне "Источник HTML" следующим кодом.
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="Q889251.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body> <form id="Form1" method="post" runat="server"> <P> </P> <P> Enter Path of process to be run (with relevant parameters) <asp:TextBox id="TextBox1" runat="server"></asp:TextBox> </P> <P> <asp:Button id="Button1" runat="server" Text="CreateProcess"></asp:Button> </P> <P> <asp:Label id="Label1" runat="server">Status:</asp:Label> </P> <P> <asp:Label id="Label2" runat="server">Impersonated Identity:</asp:Label> </P> </form> </body> </HTML>
В меню Вид выберите пункт Конструктор.
Дважды щелкните CreateProcess. Метод
Button1_Click
вставляется в код, а код отображается в области содержимого.Замените существующий
Button1_Click
метод следующим кодом.private void Button1_Click(object sender, System.EventArgs e) { IntPtr Token = new IntPtr(0); IntPtr DupedToken = new IntPtr(0); bool ret; Label2.Text+=WindowsIdentity.GetCurrent().Name.ToString(); SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.bInheritHandle = false; sa.Length = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = (IntPtr)0; Token = WindowsIdentity.GetCurrent().Token; const uint GENERIC_ALL = 0x10000000; const int SecurityImpersonation = 2; const int TokenType = 1; ret = DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken); if (ret == false) { Label1.Text +="DuplicateTokenEx failed with " + Marshal.GetLastWin32Error(); } else { Label1.Text+= "DuplicateTokenEx SUCCESS"; STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = ""; string commandLinePath; commandLinePath = TextBox1.Text; PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); ret = CreateProcessAsUser(DupedToken,null,commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, "c:\\", ref si, out pi); if (ret == false) { Label1.Text +="CreateProcessAsUser failed with " + Marshal.GetLastWin32Error(); } else { Label1.Text +="CreateProcessAsUser SUCCESS. The child PID is" + pi.dwProcessId; CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } ret = CloseHandle(DupedToken); if (ret == false) { Label1.Text+=Marshal.GetLastWin32Error(); } else { Label1.Text+="CloseHandle SUCCESS"; } } }
On the Build menu, click Build Solution.
В меню Отладка нажмите кнопку Пуск.
На странице WebForm1 введите путь к процессу, который требуется запустить. Например, введите
SystemDriver \Windows\Notepad.exe
.Щелкните СоздатьProcess.
Ссылки
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по