【发布时间】:2011-10-28 17:52:01
【问题描述】:
我在windowsPrincipal.getIdentity().getSid() 中有用户的SID 为byte[]。
如何从 SID 中获取 Active Directory 条目 (DirectoryEntry)?
【问题讨论】:
标签: directoryentry sid
我在windowsPrincipal.getIdentity().getSid() 中有用户的SID 为byte[]。
如何从 SID 中获取 Active Directory 条目 (DirectoryEntry)?
【问题讨论】:
标签: directoryentry sid
使用SecurityIdentifier类将sid从byte[]格式转换为字符串,然后直接绑定到对象:
DirectoryEntry OpenEntry(byte[] sidAsBytes)
{
var sid = new SecurityIdentifier(sidAsBytes, 0);
return new DirectoryEntry(string.Format("LDAP://<SID={0}>", sid.ToString()));
}
【讨论】:
我在 c# 中找到了这个例子
// SID must be in Security Descriptor Description Language (SDDL) format
// The PrincipalSearcher can help you here too (result.Sid.ToString())
public void FindByIdentitySid()
{
UserPrincipal user = UserPrincipal.FindByIdentity(
adPrincipalContext,
IdentityType.Sid,
"S-1-5-21-2422933499-3002364838-2613214872-12917");
Console.WriteLine(user.DistinguishedName);
}
转换为 VB.NET:
' SID must be in Security Descriptor Description Language (SDDL) format
' The PrincipalSearcher can help you here too (result.Sid.ToString())
Public Sub FindByIdentitySid()
Dim user As UserPrincipal = UserPrincipal.FindByIdentity(adPrincipalContext, IdentityType.Sid, "S-1-5-21-2422933499-3002364838-2613214872-12917")
Console.WriteLine(user.DistinguishedName)
End Sub
显然你可以:
dim de as new DirectoryEntry("LDAP://" & user.DistinguishedName)
获取 SID = S-1-5-21-*(对不起 VB.NET)
' Convert ObjectSID to a String
' http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/57452aab-4b68-4444-aefa-136b387dd06e
Dim ADpropSid As Byte()
ADpropSid = de.Properties("objectSid").Item(0)
' in my test the byte field looks like this : 01 02 00 00 00 00.......37 02 00 00
Dim SID As New System.Security.Principal.SecurityIdentifier(ADpropSid, 0)
我自己还没有测试过C#,也没有使用过转换后的版本,但是已经用上面的方法返回SDDL格式的SID了。
【讨论】:
"LDAP://" & user.DistinguishedName?您不需要指定主机名等吗?这是否要求您在具有 Active Directory 访问权限的同一台计算机上?
我发现最简单的方法是使用 LDAP 绑定。类似于尼克吉尔斯所说的。更多信息MSDN
''' <summary>
''' Gets the DirectoryEntry identified by this SecurityIdentifier.
''' </summary>
''' <param name="id">The SecurityIdentifier (SID).</param>
<System.Runtime.CompilerServices.Extension()> _
Public Function GetDirectoryEntry(ByVal id As SecurityIdentifier) As DirectoryEntry
Const sidBindingFormat As String = "LDAP://AOT/<SID={0}>"
Return New DirectoryEntry(String.Format(sidBindingFormat, id.Value))
End Function
【讨论】:
这也可以在 PowerShell 中完成,只要您有 .Net 3.5 或 4.0 可用(如果默认情况下没有,请参阅 https://gist.github.com/882528)
add-type -assemblyname system.directoryservices.accountmanagement
$adPrincipalContext =
New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
[System.DirectoryServices.AccountManagement.ContextType]::Domain)
$user = [system.directoryservices.accountmanagement.userprincipal]::findbyidentity(
$adPrincipalContext
, [System.DirectoryServices.AccountManagement.IdentityType]::Sid
, "S-1-5-21-2422933499-3002364838-2613214872-12917")
$user.DisplayName
$user.DistinguishedName
【讨论】: