8

我在用Novell.Directory.LdapC# 编写的 Xamarin 移动应用程序中使用。

使用 Novell,我可以使用基于域、用户名和密码的用户身份验证

LdapConnection.bind(username, password);

然后,我使用sAMAccountName等同于提供的用户名的 执行搜索。

毕竟这一切都成功了,我需要获取用户的objectGuid,以便我可以查询使用该 guid 作为键的外部数据库。问题是,当我从 guid 中取回 guid 时LdapSearchResults,它以某种方式进行了编码。而且我无法弄清楚如何获得这个 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();
    }
}
4

4 回答 4

13

我不确定 Novell 库是否以其他方式对其进行编码,但 System.DirectoryServices 将 GUID 作为字节数组提供。您可以使用 System.Guid 结构将其转换为可读字符串:

new Guid((System.Byte[])this.GUID).ToString()
于 2013-08-29T18:32:32.993 回答
8

ObjectGUID是一个二进制字符串(或八位字节字符串),因此当您尝试显示该值时,您可能会看到一些随机的无意义字符。

ObjectGUID实际上遵循一个完善的标准——它是一个UUID版本 4。由于我不使用C#,我无法提供工作示例,但有了这些信息,您应该能够将二进制字符串解码为可读的字符串表示形式,或者至少找到一个工作代码示例。我强烈怀疑在C#中会有一些本地类或库与 UUID/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;
}
于 2013-08-22T15:22:11.753 回答
2

在 Novell 库中,objectGUID是一个SByte数组,Byte在转换为GUID. 您还需要获取ByteValueof objectGUID,而不是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;
}
于 2015-06-25T02:56:57.867 回答
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;
}
于 2016-04-19T16:33:23.803 回答