在SQL Server中存储和检索Active Directory objectGUID

时间:2014-11-24 21:51:28

标签: sql-server active-directory

我接近完成这项工作。我需要在我们的Intranet上识别用户。我需要将该用户的objectGUID存储在SQL Server数据库表中,并能够再次检索该记录。我有几个不同的应用程序,PHP,ASP Classic和ASP.Net。我认为在SQL Server中执行AD查找可能最简单。

我可以使用本教程http://sql.dzone.com/news/querying-active-directory-thro

中的步骤连接到AD

我可以检索objectGUID以及我需要的任何其他内容,但我不确定如何将objectGUID存储在数据库中或如何使用objectGUID查询数据库。< / p>

我认为它是数据类型(128长度字节数组?)并且需要转换,但我不知道该怎么做。

从活动目录中选择记录并插入表中显示插入的数据类型objectGUID为varbinary(256)

select  *
into temp_table
from  openquery(adsi, '
select  givenName,
                sn,
                sAMAccountName,
                objectGUID              
from    ''LDAP://dc=somedomain,dc=com''
where   sAMAccountName = ''some_user''
')

为了测试,我尝试使用从上面的temp_table中检索到的objectGUID来查询AD。

declare @qry varchar(8000)
declare @var varbinary(256)
set @var = (SELECT objectGUID from temp_table)
set @qry = 'select *
from openquery(ADSI, ''
    select
    givenName, 
    sn, 
    sAMAccountName
    from ''''LDAP://DC=somedomain,DC=com'''' 
    where objectGUID = ''''+@var+''''   
    ORDER BY displayName
'')'

exec(@qry)

不返回任何行......

最初我认为这是带引号的正确语法

where objectGUID = '+@var+'

但返回错误:数据类型的运算符无效。运算符等于add,键入equals varchar

所以也许我接近错误的语法,或者仍然是数据类型问题?

提前致谢。

5 个答案:

答案 0 :(得分:1)

要在单个查询中从AD检索数据,当您请求特定的对象GUID或多个GUID时,有一种方法可以使用where子句代替from LDAP://<GUID=your guid>表达式(在单GUID的查询案例)。

查询的where子句中Active Directory对象的GUID必须具有字符串形式,其中GUID以十六进制表示的每个字节前面都带有反斜杠符号:

\1B\C1\93\F8\25\32\72\4E\8B\48\48\62\BB\44\49\7A

例如,您具有GUID:F893C11B-3225-4E72-8B48-4862BB44497A。首先,您必须将其转换为binary(16)类型(长度为16的字节数组),然后转换为十六进制字符串,最后像上面的示例一样插入反斜杠:

declare @g uniqueidentifier = 'F893C11B-3225-4E72-8B48-4862BB44497A';
declare @gs nvarchar(max);

set @gs = CONVERT(nvarchar(max), CONVERT(binary(16), @g), 2);

declare @c int = 16;
while @c > 0
begin
set @c = @c - 1;
set @gs = STUFF(@gs, (2 * @c) + 1, 0, '\');
end;

declare @q nvarchar(max) = 
'select * from openquery(AD, 
'' select cn from ''''LDAP://DC=domain,DC=com'''' 
where objectGUID = ''''' + @gs + '''''  
'')';

exec(@q);

上面的代码创建以下查询:

select * from openquery(AD, 'select cn from ''LDAP://DC=domain,DC=com'' where objectGUID = ''\1B\C1\93\F8\25\32\72\4E\8B\48\48\62\BB\44\49\7A'' ')

答案 1 :(得分:0)

您是否在TSQL中尝试过CASTCONVERThttp://msdn.microsoft.com/en-us/library/ms187942.aspx有几个例子。

答案 2 :(得分:0)

目前还不清楚你是什么意思&#34;如何使用objectGUID&#34;查询数据库,但如果你想知道确切的数据类型,有两种方法:

  1. 如果您至少使用SQL Server 2012,则可以尝试sp_describe_first_result_set。它有几个限制因此不适用于所有情况。

  2. 您可以将结果转储到临时表,然后检查其结构:

    SELECT fields
    INTO #tmp
    FROM openquery(...);
    
    EXEC tempdb.dbo.sp_help '#tmp';
    
  3. 在创建用于存储值的列或声明局部变量时,使用返回的任何数据类型(可能是BINARY(128)VARBINARY(128))。

    修改
    所以我们现在知道objectGUID是一个VARBINARY(256)。为了在查询中正确使用它,请从已转义的字符串中的转义字符串中删除三组单引号。此外,我们需要将VARBINARY转换为VARCHAR,以便它可以连接到动态SQL字符串中。使用CONVERT功能时,请务必使用&#34;样式&#34;将十六进制数字转换为十六进制数字字符串的1的数量(即&#34; 0x12D5&#34;);如果你没有指定&#34;样式&#34;默认操作是转换为由这些十六进制数字表示的字符(即&#34; Hello!&#34;)。

    DECLARE @Query VARCHAR(8000),
            @ObjectGUID VARBINARY(256);
    
    SELECT @ObjectGUID = objectGUID
    FROM   temp_table;
    
    SET @Query = 'SELECT *
    FROM OPENQUERY(ADSI, ''
        SELECT
        givenName, 
        sn, 
        sAMAccountName
        FROM ''''LDAP://DC=somedomain,DC=com'''' 
        WHERE objectGUID = ' + CONVERT(VARCHAR(300), @ObjectGUID, 1) + '
        ORDER BY displayName;
     '')';
    
    PRINT @Query; -- see what SQL is being executed
    EXEC(@Query);
    

答案 3 :(得分:0)

我还在我的项目中将AD中的objectGUID存储到SQL服务器中,并使用uniqueidentifier。 (但是我不使用OpenQuery,而是使用Windows服务不断从AD同步并填充数据库。)

虽然从AD对象获取的对象出现为二进制数组(varbinary),但是 它实际上代表一个GUID,SQL中相应的类型是uniqueidentifier 并且GUID仅为16字节(128位)。

这未经过测试,但请尝试以下方式:

Select CONVERT(uniqueIdentifier,objectGUID) as Id, ...
FROM OpenQuery(ADSI,
    'SELECT objectGUID, ...
     FROM ...
     WHERE...')

答案 4 :(得分:0)

我无法在where子句中使用objectGUID,但我发现我可以直接绑定到objectGUID,它给出了相同的最终结果。

DECLARE @qry varchar(8000) 
DECLARE @ObjectGUID uniqueIdentifier

SET @ObjectGUID = (SELECT objectGUID FROM temp_table)

SET @qry = 'select *
FROM openquery(ADSI, ''
    SELECT  givenName,
                sn,
                sAMAccountName,
                objectGUID              
from    ''''LDAP://<GUID=' + CAST(@ObjectGUID as CHAR(36)) + '>''''
'')'

EXEC(@qry)