2010-01-27 17 views
8

Windows oturum açma SID'si nasıl C# .net? (kullanıcı SID'sini değil, her oturum için benzersiz yeni bir tane)Oturum açma SID'si nasıl edinilir C#

+0

Windwos ortamında SID, Güvenlik Kimliği değil Session Id. Oturum kimliğini kullanmak için 'System.Diagnostics.Process.GetCurrentProcess() kullanın. SessionId' Daha fazla bilgi için [burada yanıtım] bölümüne bakın (http://stackoverflow.com/a/16942663/725903) – mistika

cevap

6

Korkarım P/Invoke kullanmaya başvurmanız gerekiyor. pinvoke.net de bunu nasıl bir örnek (sayfanın altına bakınız) vardır:

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

Sadece bir satır değiştirerek örnek değiştirdiğinizi unutmayın, ben tam olarak neye ihtiyacınız olduğu TOKEN_INFORMATION_CLASS.TokenSessionId ile TOKEN_INFORMATION_CLASS.TokenUser yerini .

Bu yardımcı olur umarım.

Güncelleme:

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.: Burada kodun (en azından benim makinede) çalışma var X64 makinemde test ettim, bu yüzden lütfen TokenInformation.ToInt64() kod parçasına dikkat edin, belki de TokenInformation.ToInt32()

+0

Maalesef çalışmıyor. Hiçbir şey döndürmez. Buna göre (http://msdn.microsoft.com/en-us/library/aa379626%28VS.85%29.aspx), yalnızca terminal sunucusunda çalışır, bu yüzden ihtiyacım olan oturum kimliği olmayabilir. – Jos

+0

Kodun başka bir sürümünü ekledim, makinemde çalışıyor. Bir şey açık değilse bana sormaya çekinmeyin. –

+0

Teşekkürler! Bu mükemmel çalışıyor. TokenGroups yerine TokenLogonSid kullandım, ancak sadece Windows Vista ve 7 için çalışıyor. – Jos

1

System.Security.Principal.WindowsIdentity.GetCurrent(). User.AccountDomainSid - hile yapabilir?

+1

It * not * Oturum açma oturumu kimliği SilverSkin –

+1

sordu kullanıcı SID oturumları arasında değişmeden kalır, ancak her oturum açma için bir belirteci oluşturulur, bu üzerinden erişilebilmeli ... GetCurrent(). User.Token? – SilverSkin

+0

Simge gerçekten ihtiyacım olan şeydir, ancak kullanılabilir bir SID'ye dönüştürmem gerekiyor. – Jos

1

ile değiştirin. Bunun eski bir yazı olduğunu biliyorum. ICA oturum kimliğini ve RDP oturum kimliğini bir programın her bir uzak bağlantı türü için doğru değişkenleri toplamasını sağlamak zorunda kaldığımdan bu soruna rastladım. Geçerli oturum kimliği, Regedit HKEY_CURRENT_USER \ Remote * içinde bulunur. WTS'ye herhangi bir alternatif bulamadığım için çözümümü buraya gönderiyorum.

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

}