2011-09-29 101 views
3

在.net中,我可以使用域和用戶名創建一個NTAccount,並獲取它的SID。將SID轉換爲C#中的用戶名#

但我無法使用翻譯功能將SID轉換回NTAccount。

new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString(); 

而這種雙向轉換代碼在域控制器上運行沒有問題。

也許有些配置錯了?

+0

[可以通過SID解析顯示用戶名的最佳方式?](http://stackoverflow.com/questions/380031/the-best-way-to-resolve-display-username-by-sid) –

回答

4

SecurityIdentifier.Translate()方法僅適用於域帳戶,因此可能您的計算機未連接到域。要將本地SID解析爲帳戶名稱,可以使用Win32 API函數LookupAccountSid(),例如here

+0

該機器已經使用域帳戶登錄到域,該帳戶不存在於本地 – user970444

+0

@ user970444嗯..奇怪可能是一些訪問域控制器的問題,無論如何,LookupAccountSid可以幫助你找到用戶名,即使它不是本地帳戶 – Alexander

1

而不是使用SecurityIdentifier,您可以在.NET中使用更容易和更通用的DirectoryServices。

在CodeProject上,有這樣一個很好的示例: http://www.codeproject.com/KB/cs/getusersid.aspx

的代碼是:

private string GetSid(string strLogin) 
{ 
    string str = ""; 
    // Parse the string to check if domain name is present. 
    int idx = strLogin.IndexOf('\\'); 
    if (idx == -1) 
    { 
     idx = strLogin.IndexOf('@'); 
    } 

    string strDomain; 
    string strName; 

    if (idx != -1) 
    { 
     strDomain = strLogin.Substring(0, idx); 
     strName = strLogin.Substring(idx+1); 
    } 
    else 
    { 
     strDomain = Environment.MachineName; 
     strName = strLogin; 
    } 


    DirectoryEntry obDirEntry = null; 
    try 
    { 
     Int64 iBigVal = 5; 
     Byte[] bigArr = BitConverter.GetBytes(iBigVal); 
     obDirEntry = new DirectoryEntry("WinNT://" + 
           strDomain + "/" + strName); 
     System.DirectoryServices.PropertyCollection 
          coll = obDirEntry.Properties; 
     object obVal = coll["objectSid"].Value; 
     if (null != obVal) 
     { 
      str = this.ConvertByteToStringSid((Byte[])obVal); 
     } 

    } 
    catch (Exception ex) 
    { 
     str = ""; 
     Trace.Write(ex.Message); 
    } 
    return str; 
} 

private string ConvertByteToStringSid(Byte[] sidBytes) 
{ 
    StringBuilder strSid = new StringBuilder(); 
    strSid.Append("S-"); 
    try 
    { 
     // Add SID revision. 
     strSid.Append(sidBytes[0].ToString()); 
     // Next six bytes are SID authority value. 
     if (sidBytes[6] != 0 || sidBytes[5] != 0) 
     { 
      string strAuth = String.Format 
       ("0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}", 
       (Int16)sidBytes[1], 
       (Int16)sidBytes[2], 
       (Int16)sidBytes[3], 
       (Int16)sidBytes[4], 
       (Int16)sidBytes[5], 
       (Int16)sidBytes[6]); 
      strSid.Append("-"); 
      strSid.Append(strAuth); 
     } 
     else 
     { 
      Int64 iVal = (Int32)(sidBytes[1]) + 
       (Int32)(sidBytes[2] << 8) + 
       (Int32)(sidBytes[3] << 16) + 
       (Int32)(sidBytes[4] << 24); 
      strSid.Append("-"); 
      strSid.Append(iVal.ToString()); 
     } 

     // Get sub authority count... 
     int iSubCount = Convert.ToInt32(sidBytes[7]); 
     int idxAuth = 0; 
     for (int i = 0; i < iSubCount; i++) 
     { 
      idxAuth = 8 + i * 4; 
      UInt32 iSubAuth = BitConverter.ToUInt32(sidBytes, idxAuth); 
      strSid.Append("-"); 
      strSid.Append(iSubAuth.ToString()); 
     } 
    } 
    catch (Exception ex) 
    { 
     Trace.Warn(ex.Message); 
     return ""; 
    } 
    return strSid.ToString(); 
} 

還有從SID轉換的文章中字節至字符串。

+1

「更容易」......;) – JoelFan

+0

問題是:SID - >顯示用戶名稱 您的回答是:用戶帳戶名稱 - > SID –