2013-08-22 38 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; 
} 
相关问题