2010-01-27 57 views
8

Làm cách nào để truy xuất SID Windows Logon trong C# .net? (không phải là SID người dùng, nhưng duy nhất một SID mới cho mỗi phiên)Cách nhận SID đăng nhập trong C#

+0

Trong môi trường Windwos SID là viết tắt của Mã định danh bảo mật, không phải là Id phiên. Để có được Session Id sử dụng 'System.Diagnostics.Process.GetCurrentProcess(). SessionId' Để biết thêm chi tiết, hãy xem [câu trả lời của tôi ở đây] (http://stackoverflow.com/a/16942663/725903) – mistika

Trả lời

6

Tôi e rằng bạn phải sử dụng P/Invoke. Có một ví dụ làm thế nào để làm điều đó tại pinvoke.net (xin vui lòng xem cuối trang):

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

Xin lưu ý rằng tôi đã thay đổi ví dụ bằng cách thay đổi chỉ một dòng, tôi đã thay thế TOKEN_INFORMATION_CLASS.TokenUser với TOKEN_INFORMATION_CLASS.TokenSessionId đó là chính xác những gì bạn cần .

Hy vọng điều này sẽ hữu ích.

Cập nhật: Đây là làm việc (ít nhất là trên máy tính của tôi) mã:

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; 
     } 
    } 
} 

N.B. Tôi đã thử nghiệm trên máy x64 của mình, vì vậy, hãy chú ý đến mã TokenInformation.ToInt64(), có thể bạn nên thay thế bằng TokenInformation.ToInt32()

+0

Không hoạt động không may. Nó không trả lại gì cả. Theo điều này (http://msdn.microsoft.com/en-us/library/aa379626%28VS.85%29.aspx), nó chỉ hoạt động trên máy chủ đầu cuối, vì vậy nó có thể không phải là id phiên tôi cần. – Jos

+0

Tôi đã thêm một phiên bản mã khác, nó hoạt động trên máy của tôi. Xin vui lòng hỏi tôi nếu có điều gì đó không rõ ràng. –

+0

Cảm ơn! Cái này hoạt động hoàn hảo. Tôi đã sử dụng TokenLogonSid thay vì TokenGroups, nhưng nó chỉ hoạt động với Windows Vista và 7. – Jos

1

System.Security.Principal.WindowsIdentity.GetCurrent(). User.AccountDomainSid - có thể thực hiện thủ thuật này không?

+1

Đó là * không * ID phiên đăng nhập SilverSkin hỏi về –

+1

Tôi nghĩ rằng SID người dùng vẫn không thay đổi giữa các phiên, nhưng đối với mỗi lần đăng nhập một mã thông báo được tạo, bạn có thể truy cập thông qua ... GetCurrent(). User.Token? – SilverSkin

+0

Mã thông báo thực sự là những gì tôi cần, nhưng tôi phải chuyển đổi sang SID có thể sử dụng được. – Jos

1

Tôi biết đây là một bài đăng cũ. Chỉ cần chạy vào vấn đề này vì tôi đã có được ID phiên ICA và ID phiên RDP để có một chương trình thu thập các biến chính xác cho từng loại kết nối từ xa. ID phiên hiện tại nằm trong Regedit HKEY_CURRENT_USER \ Remote *. Vì tôi không thể tìm thấy bất kỳ giải pháp thay thế nào cho WTS, tôi đang đăng giải pháp của mình ở đây.

// 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(); 
     } 
    } 

} 
Các vấn đề liên quan