2013-08-22 81 views
4

我在用C#編寫的Xamarin移動應用程序中使用Novell.Directory.Ldap如何將Active Directory objectGuid轉換爲可讀的字符串?

使用Novell,我可以基於域名,用戶名和密碼的用戶進行身份驗證使用

LdapConnection.bind(username, password); 

然後,我執行搜索,使用sAMAccountName,這相當於提供的用戶名。

畢竟,這成功的工作,我需要得到用戶的objectGuid,以便我可以查詢外部數據庫,使用該guid作爲關鍵。問題是,當我從LdapSearchResults得到guid時,它以某種方式編碼。我無法弄清楚如何獲得這個GUID的可讀字符串表示。

有沒有人有關於此的更多信息?我會想象那個guid是以某種方式編碼的,但是它是如何編碼的,我不知道。我試過

System.Convert.FromBase64String 

而且沒有幫助。我感謝幫助人員,讓我知道我是否可以發佈任何有用的信息。

private void Login() 
{ 
    if (LOG.isInfoEnabled()) 
    { 
     LOG.info("Attempting LDAP logon . . ."); 

     if (LOG.isDebugEnabled()) 
     { 
      LOG.debug("Host: " + this.ldapHost); 
      LOG.debug("Port: " + this.ldapPort); 
      LOG.debug("SearchBase: " + this.ldapSearchBase); 
     } 
    } 

    LdapConnection conn = new LdapConnection(); 

    try 
    { 
     conn.Connect(this.ldapHost, this.ldapPort); 

     if (LOG.isDebugEnabled()) 
     { 
      LOG.debug("connected?: " + conn.Connected.ToString()); 
     } 
    } 
    catch (Exception e) 
    { 
     LOG.error("An exception occurred while attempting to connect to AD server!", e); 

     // INFORM USER ABOUT ERROR 
     authError(Resource.String.error_unknown); 
    } 

    if (!string.IsNullOrEmpty(this.editTextUserName.Text) && !string.IsNullOrEmpty(this.editTextPassword.Text)) 
    { 
     // HIDE KEYBOARD 
     var imm = (InputMethodManager)GetSystemService(Context.InputMethodService); 
     imm.HideSoftInputFromWindow(editTextPassword.WindowToken, HideSoftInputFlags.NotAlways); 

     // HIDE 'LOGON' BUTTON WHILE LOGGING ON 
     this.buttonLogin.Visibility = ViewStates.Invisible; 

     try 
     { 
      // PERFORM AUTHENTICATION 
      conn.Bind(this.userName, this.userPassword); 

      if (LOG.isDebugEnabled()) 
      { 
       LOG.debug("conn.Bound?: " + conn.Bound); 
      } 

      if (conn.Bound) 
      { 
       if (LOG.isDebugEnabled()) 
       { 
        LOG.debug("authentication successful"); 
       } 

       string[] name = this.userName.Split('\\'); 
       LOG.debug("name[0]: " + name[0]); 
       LOG.debug("name[1]: " + name[1]); 

       string filter = "(sAMAccountName=" + name[1] + ")"; 
       string guid = ""; 

       LdapSearchResults searchResults = conn.Search(
        this.ldapSearchBase, // search base 
        LdapConnection.SCOPE_SUB, // search scope 
        filter, // filter 
        null, // attributes 
        false); // attributes only 

       while (searchResults.hasMore()) 
       { 
        LdapEntry nextEntry = null; 

        try 
        { 
         nextEntry = searchResults.next(); 
         guid = nextEntry.getAttribute("objectGUID").StringValue; 
        } 
        catch (LdapException e) 
        { 
         LOG.error("An exception occurred while attempting to get next search result!", e); 
         continue; 
        } 
       } 

       Intent intent = new Intent(this, typeof(DashboardActivity)); 
       intent.PutExtra("guid", guid); 

       StartActivity(intent); 
      } 
      else 
      { 
       // INFORM USER ABOUT ERROR 
       authError(Resource.String.error_auth); 
      } 
     } 
     catch (LdapException ldape) 
     { 
      LOG.error("An exception occurred while attempting to authenticate user credentials!", ldape); 

      // INFORM USER ABOUT ERROR 
      authError(Resource.String.error_auth); 
     } 
     finally 
     { 
      conn.Disconnect(); 
     } 
    } 
    else 
    { 
     conn.Disconnect(); 
    } 
} 
+0

你說你可以使用域和用戶名綁定。你究竟如何格式化?我遇到了麻煩。在這裏看到我的問題:http://stackoverflow.com/q/30773555/3799847 –

回答

6

的objectGUID是一個二進制字符串(或字節串),那麼你很可能看到的是一些隨機的無意義的字符,當您試圖顯示的值。

ObjectGUID實際上遵循完善的標準 - 它是一個UUID version 4。 由於我不與C#我不能提供工作的例子,但有了這些信息,你應該能夠將二進制字符串解碼成可讀的字符串表示或至少找到一個工作的代碼示例。我強烈懷疑在C#中會有一些本地類或圖書館與UUIDs/Guids一起使用。

如果你不介意看一個php的例子,看看在的轉換在php中。

這裏是有問題的功能。它期望從服務器返回的原始二進制形式的$ guid。

function _to_p_guid($guid) 
{ 
$hex_guid = unpack("H*hex", $guid); 
$hex = $hex_guid["hex"]; 

$hex1 = substr($hex, -26, 2) . substr($hex, -28, 2) . substr($hex, -30, 2) . substr($hex, -32, 2); 
$hex2 = substr($hex, -22, 2) . substr($hex, -24, 2); 
$hex3 = substr($hex, -18, 2) . substr($hex, -20, 2); 
$hex4 = substr($hex, -16, 4); 
$hex5 = substr($hex, -12, 12); 

$guid = $hex1 . "-" . $hex2 . "-" . $hex3 . "-" . $hex4 . "-" . $hex5; 

return $guid; 
} 
+0

我得到了404。你有沒有機會在其他地方使用PHP?我目前有問題,這返回錯誤的GUID:echo bin2hex($ user_info ['objectguid'] [0]); – frax

+1

我已更新鏈接(我最近將源代碼移動了一下),並直接在答案中提供了有問題的示例代碼。我很抱歉! –

7

我不知道如果Novell庫編碼它在一些其他的方式,但的System.DirectoryServices提供GUID的字節數組。就可以得到此使用的System.Guid結構可讀的字符串:

new Guid((System.Byte[])this.GUID).ToString() 
+0

這是一個非常準確的答案。謝謝。 – Shishdem

0

在Novell的文庫,objectGUIDSByte陣列,其需要被轉換成一個GUID之前被轉換爲Byte陣列。您還需要獲得的ByteValue,而不是StringValue

try 
{ 
    nextEntry = searchResults.next(); 
    guid = new Guid((Byte[])(Array)nextEntry.getAttribute("objectGUID").ByteValue); 
} 
catch (LdapException e) 
{ 
    LOG.error("An exception occurred while attempting to get next search result!", e); 
    continue; 
} 
0

對我來說,解決辦法是在實例如下方式GUID:

internal string GetProperty(SearchResult searchResult, String PropertyName) 
{ 
    string retVal = string.Empty; 
    if (searchResult.Properties.Contains(PropertyName)) 
    { 
     if (PropertyName == "objectguid") 
     { 
      Guid _guid = new Guid((Byte[])(Array)searchResult.Properties[PropertyName][0]); 
      retVal = _guid.ToString(); 
     } 
     else 
      retVal = searchResult.Properties[PropertyName][0].ToString();  } 
    return retVal; 
} 
相關問題