簡體   English   中英

如何在C#中獲取登錄SID

[英]How to get the logon SID in C#

如何在 C# .net 中檢索 Windows 登錄 SID? (不是用戶 SID,而是每個會話的唯一新 SID)

恐怕您不得不求助於使用 P/Invoke。 pinvoke.net 上有一個示例(請參閱頁面底部):

Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenSessionId , TokenInformation , TokenInfLength , out TokenInfLength );

請注意,我通過改變只有一條線路改變的例子,我換成TOKEN_INFORMATION_CLASS.TokenUserTOKEN_INFORMATION_CLASS.TokenSessionId這正是你需要的。

希望這可以幫助。

更新:這是工作(至少在我的機器上)代碼:

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace LinqTest
{
    public class ClsLookupAccountName
    {
        public const uint SE_GROUP_LOGON_ID = 0xC0000000; // from winnt.h
        public const int TokenGroups = 2; // from TOKEN_INFORMATION_CLASS

        enum TOKEN_INFORMATION_CLASS
        {
            TokenUser = 1,
            TokenGroups,
            TokenPrivileges,
            TokenOwner,
            TokenPrimaryGroup,
            TokenDefaultDacl,
            TokenSource,
            TokenType,
            TokenImpersonationLevel,
            TokenStatistics,
            TokenRestrictedSids,
            TokenSessionId,
            TokenGroupsAndPrivileges,
            TokenSessionReference,
            TokenSandBoxInert,
            TokenAuditPolicy,
            TokenOrigin
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SID_AND_ATTRIBUTES
        {
            public IntPtr Sid;
            public uint Attributes;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct TOKEN_GROUPS
        {
            public int GroupCount;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            public SID_AND_ATTRIBUTES[] Groups;
        };

        // Using IntPtr for pSID instead of Byte[]
        [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool ConvertSidToStringSid(IntPtr pSID, out IntPtr ptrSid);

        [DllImport("kernel32.dll")]
        static extern IntPtr LocalFree(IntPtr hMem);

        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool GetTokenInformation(
            IntPtr TokenHandle,
            TOKEN_INFORMATION_CLASS TokenInformationClass,
            IntPtr TokenInformation,
            int TokenInformationLength,
            out int ReturnLength);

        public static string GetLogonId()
        {
            int TokenInfLength = 0;
            // first call gets lenght of TokenInformation
            bool Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenGroups, IntPtr.Zero, TokenInfLength, out TokenInfLength);
            IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength);
            Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenGroups, TokenInformation, TokenInfLength, out TokenInfLength);

            if (!Result)
            {
                Marshal.FreeHGlobal(TokenInformation);
                return string.Empty;
            }

            string retVal = string.Empty;
            TOKEN_GROUPS groups = (TOKEN_GROUPS)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_GROUPS));
            int sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES());
            for (int i = 0; i < groups.GroupCount; i++)
            {
                SID_AND_ATTRIBUTES sidAndAttributes = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure(
                    new IntPtr(TokenInformation.ToInt64() + i * sidAndAttrSize + IntPtr.Size), typeof(SID_AND_ATTRIBUTES));
                if ((sidAndAttributes.Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID)
                {
                    IntPtr pstr = IntPtr.Zero;
                    ConvertSidToStringSid(sidAndAttributes.Sid, out pstr);
                    retVal = Marshal.PtrToStringAuto(pstr);
                    LocalFree(pstr);
                    break;
                }
            }

            Marshal.FreeHGlobal(TokenInformation);
            return retVal;
        }
    }
}

注意我在我的 x64 機器上測試過,所以請密切關注TokenInformation.ToInt64()這段代碼,也許你應該用TokenInformation.ToInt32()替換它

System.Security.Principal.WindowsIdentity.GetCurrent().User.AccountDomainSid - 可能有用嗎?

我知道這是一個舊帖子。 剛遇到這個問題,因為我必須獲得 ICA 會話 ID 和 RDP 會話 ID,才能讓程序為每種類型的遠程連接收集正確的變量。 當前會話 ID 位於 Regedit HKEY_CURRENT_USER\\Remote*。 由於我找不到 WTS 的任何替代方案,因此我在此處發布了我的解決方案。

    // Prints out ICA or RDP session ID of current user 

using System;
using Microsoft.Win32;

namespace ViaRegedit
{
    class Program03
    {
        static void Main(string[] args)
        {
            // Obtain an instance of RegistryKey for the CurrentUser registry 
            RegistryKey rkCurrentUser = Registry.CurrentUser;
            // Obtain the test key (read-only) and display it.
            RegistryKey rkTest = rkCurrentUser.OpenSubKey("Remote");
            foreach (string valueName in rkTest.GetSubKeyNames())
            {
                //Getting path to RDP/Citrix session ID
                string RDPICApath = "";
                if (rkTest.OpenSubKey(valueName) != null && rkTest.OpenSubKey(valueName) != null) { RDPICApath = rkTest.OpenSubKey(valueName).ToString(); }
                Console.WriteLine("Getting CurrentUser ICA-RDP path from string = " + RDPICApath);

                //Seperating RDPICApath to get session number
                string RDPICAnumber = RDPICApath.Substring(RDPICApath.LastIndexOf('\\') + 1);
                Console.WriteLine("Current User RDPICAnumber = " + RDPICAnumber);
            }
            rkTest.Close();
            rkCurrentUser.Close();
            Console.ReadLine();
        }
    }

}

我只是花了很長時間使用 TOKEN_USER 等獲取 SID,然后在 C# 中發現了一個快捷方式。 您仍然需要獲取進程句柄(例如https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.handle?view=netcore-3.1 ),然后是帶有 P/invoke 的令牌:

OpenProcessToken(hProcess, TOKEN_READ, out IntPtr hToken))

但是一旦你有了令牌,你就不需要做任何令人討厭的GetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenUser...你只需要使用的東西:

var winId = System.Security.Principal.WindowsIdentity(hToken);

...和 ​​BOOM,您可以從 winId 中獲取用戶所需的所有信息(包括 SID)。

之后不要忘記CloseHandle(hToken)和 hProcess !

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM