Microsoft ASP.NET'de kimliğine bürünülen kullanıcının bağlamı altında çalışan bir işlem oluşturma

Bu makalede, kimliğine bürünülen kullanıcının bağlamı altında çalışan bir işlemin nasıl ortaya konuldığı açıklanır.

Orijinal ürün sürümü: ASP.NET
Özgün KB numarası: 889251

Giriş

Bu adım adım makalede, ASP.NET sayfalarında kimliğine bürünülen kullanıcının bağlamı altında çalışan bir işlemin nasıl ortaya çıkarıldığı açıklanır. Kimliğine bürünülen kullanıcının bağlamı altında çalışan bir işlem oluşturmak için yöntemini kullanamazsınız System.Diagnostics.Process.Start . Bunun nedeni, ASP.NET içinde kimliğe bürünme işleminin işlem düzeyinde değil iş parçacığı düzeyinde gerçekleştirilmesidir. Bu nedenle, ASP.NET oluşturduğunuz tüm işlemler kimliğine bürünülen bağlam altında değil, ASP.NET çalışan işleminin bağlamında çalıştırılır.

Tekniğin açıklaması

Bu sorunu geçici olarak çözmek için aşağıdaki Win32 API'lerine platform çağrısı (P/Invoke) çağrıları yapmanız gerekir:

  • işlevi, CreateProcessAsUser parametrelerden birinde belirtilen güvenlik belirtecinin kimliği altında bir işlem oluşturur. Ancak, işlevine çağrı CreateProcessAsUser birincil belirteç gerektirir. Bu nedenle, kimliğine bürünülen belirteci birincil belirteçe dönüştürmeniz gerekir.

  • İşlev, DuplicateTokenEx kimliğine bürünülen bir belirteci birincil belirteçe dönüştürür. İşlev çağrısı bu CreateProcessAsUser birincil belirteci kullanır.

Not

İşlev çağrısının CreateProcessAsUser çalışması için, kimliğine bürünülen kullanıcıya aşağıdaki güvenlik kullanıcı hakları atanmalıdır:

  • Windows çalıştıran bir bilgisayarda İşlem düzeyi belirteci değiştir kullanıcı hakkını ve Kotaları artırma kullanıcı hakkını kimliğine bürünülen kullanıcıya atayın.
  • Windows Server veya Windows XP çalıştıran bir bilgisayarda, kimliğine bürünülen kullanıcıya İşlem düzeyi belirteç kullanıcısını değiştirme hakkını atayın.

İşlem oluşturma adımları

Microsoft, programlama örneklerini yalnızca gösterim amacıyla sağlar; örtülü veya açık garanti vermez. Buna zımni garantiler, satılabilirlik veya belirli bir amaca uygunluk da dahildir, ancak bunlarla sınırlı değildir. Bu makale, gösterilen programlama dilini ve yordamları oluşturmak ve hata ayıklamak amacıyla kullanılan araçları kullanmayı bildiğinizi varsayar. Microsoft destek mühendisleri, belirli bir yordamın işlevselliğinin açıklanmasına yardımcı olabilir, ancak gereksinimlerinizi karşılamaya yönelik olarak ek işlevsellik sağlamak veya yordamlar geliştirmek amacıyla bu örnekleri değiştirmezler. Kimliğine bürünülen kullanıcının bağlamı altında çalışan bir işlem oluşturmak için şu adımları izleyin:

  1. Visual Studio .NET'te yeni bir Visual C# ASP.NET Web uygulaması oluşturun ve uygulamayı Q889251 olarak adlandırın.

  2. WebForm1.aspx dosyasını kod görünümünde açın.

  3. WebForm1.aspx dosyasında aşağıdaki deyimleri using kod bloğuna ekleyin.

    using System.Runtime.InteropServices;
    using System.Security.Principal;
    
  4. Aşağıdaki kod satırına benzeyen kod satırını bulun.

    public class WebForm1 : System.Web.UI.Page
    
  5. 4. adımda tanımlanan kod satırından sonra aşağıdaki kodu ekleyin.

    [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);
    
  6. Çözüm Gezgini'daWebForm1.aspx sağ tıklayın ve ardından Aç'a tıklayın. Web formu tasarım görünümünde açılır.

  7. Görünüm menüsünde HTML Kaynağı'na tıklayın.

  8. HTML Kaynağı penceresindeki tüm mevcut kodu aşağıdaki kodla değiştirin.

    <%@ 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>&nbsp;</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>
    
  9. Görünüm menüsünde Tasarım'a tıklayın.

  10. CreateProcess'e çift tıklayın. Button1_Click yöntemi koda eklenir ve kod içerik bölmesinde görünür.

  11. Mevcut Button1_Click yöntemi aşağıdaki kodla değiştirin.

    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";
            }
        }
    }
    
  12. Derleme menüsünde Çözüm Oluştur'a tıklayın.

  13. Hata Ayıkla menüsünde Başlat'a tıklayın.

  14. WebForm1 sayfasında, başlatmak istediğiniz işlemin yolunu yazın. Örneğin, yazın SystemDriver \Windows\Notepad.exe.

  15. Oluşturİşlem'e tıklayın.

Başvurular