我有一个字符串,我从LDAP获取Active Directory组成员资格,我需要解析它以检查用户是否是AD组的成员。是否有一个类可以为我解析这个?
示例:
CN=Foo Group Name,DC=mydomain,DC=com
答案 0 :(得分:7)
如果您不想添加其他依赖项,只想解析字符串..
只需使用string.Split即可轻松解析此类型的字符串。要获得CN值,就像......
string[] split = "CN=Foo Group Name,DC=mydomain,DC=com".Split(',');
List<string> cnValues = new List<string>();
foreach(string pair in split){
string[] keyValue=pair.Split('=');
if(keyValue[0]=="CN")
cnValues.Add(keyValue[1]);
}
答案 1 :(得分:6)
这些被称为专有名称。
CodeProject有一个解析器项目,可以满足您的需求:http://www.codeproject.com/KB/IP/dnparser.aspx
答案 2 :(得分:4)
此外,如果您在AD中查询组成员,您将能够直接比较所有成员的distinguishedName,而无需通过DirectoryEntry
命名空间的System.DirectoryServices
类解析代码。 / p>
否则,我只是不知道某个地方的某个类。 =)
希望无论如何都有帮助!
编辑#1
这是我从AD和System.DirectoryServices
命名空间学习了很多东西的链接:Howto: (Almost) Everything In Active Directory via C#
如果您仍然需要,我将在几天内为您提供示例代码,我将使用System.DirectoryServices.DirectorySearcher
对象类来检索组的成员。
我希望这个链接对我有所帮助! =)
编辑#2
这是我告诉你的代码示例。这样可以更有效地查询AD,而无需在AD上工作。
public IList<string> GetMembers(string groupName) {
if (string.IsNullOrEmpty(groupName))
throw new ArgumentNullException("groupName");
IList<string> members = new List<string>();
DirectoryEntry root = new DirectoryEntry(@"LDAP://my.domain.com");
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = root;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("member");
searcher.Filter = string.Format("(&(objectClass=group)(sAMAccountName={0}))", groupName);
SearchResult result = searcher.FindOne();
DirectoryEntry groupFound = result.GetDirectoryEntry();
for (int index = 0; index < ((object[])groupFound.Properties["member"].Value).Length; ++index)
members.Add((string)((object[])groupFound.Properties["member"].Value)[index]);
return members;
}
免责声明:此代码按原样提供。我在我的本地机器上进行了测试,效果非常好。但是因为我不得不在这里重新输入它,因为我不能只是复制粘贴它,我可能在输入时犯了一些错误,我希望不会发生这种错误。
答案 3 :(得分:3)
要解析DistinquishedName,您必须注意转义字符。这是一个正确解析字符串并返回键值对列表的方法。
public static List<KeyValuePair<string, string>> ParseDistinguishedName(string input)
{
int i = 0;
int a = 0;
int v = 0;
var attribute = new char[50];
var value = new char[200];
var inAttribute = true;
string attributeString, valueString;
var names = new List<KeyValuePair<string, string>>();
while (i < input.Length)
{
char ch = input[i++];
switch(ch)
{
case '\\':
value[v++] = ch;
value[v++] = input[i++];
break;
case '=':
inAttribute = false;
break;
case ',':
inAttribute = true;
attributeString = new string(attribute).Substring(0, a);
valueString = new string(value).Substring(0, v);
names.Add(new KeyValuePair<string, string>(attributeString, valueString));
a = v = 0;
break;
default:
if (inAttribute)
{
attribute[a++] = ch;
}
else
{
value[v++] = ch;
}
break;
}
}
attributeString = new string(attribute).Substring(0, a);
valueString = new string(value).Substring(0, v);
names.Add(new KeyValuePair<string, string>(attributeString, valueString));
return names;
}
static void Main(string[] args)
{
const string TestString = "CN=BY2STRAKRJOB2,OU=MSNStorage,OU=RESOURCE,OU=PRODUCTION,DC=phx,DC=gbl,STREET=street address,L=locality Name,C=Country Name,UID=user id,STUFF=\\,\\.\\+\"<>;\\=\\0A";
var names = ParseDistinguishedName(TestString);
foreach (var pair in names)
{
Console.WriteLine("{0} = {1}", pair.Key, pair.Value);
}
}
答案 4 :(得分:2)
Using System.DirectoryServices;
namespace GetGroups
{
public string GetGroupName(string LDAPGroupEntry)
{
// LDAPGroupEntry is in the form "LDAP://CN=Foo Group Name,DC=mydomain,DC=com"
DirectoryEntry grp = new DirectoryEntry(LDAPGroupEntry);
return grp.Properties["Name"].Value.ToString();
}
}
答案 5 :(得分:0)
要回答解析问题,请将PInvoke与DsGetRdnW
一起使用。有关代码,请参阅我对其他问题的回答:https://stackoverflow.com/a/11091804/628981。
但听起来你做错了。首先,获取目标组的SID:
string targetGroupName = //target group name;
DirectorySearcher dsTargetGroup = new DirectorySearcher();
dsTargetGroup.Filter = string.Format("(sAMAccountName={0})", targetGroupName);
SearchResult srTargetGroup = dsTargetGroup.FindOne();
DirectoryEntry deTargetGroup = srTargetGroup.GetDirectoryEntry();
byte[] byteSid = (byte[])deTargetGroup.Properties["objectSid"].Value;
SecurityIdentifier targetGroupSid = new SecurityIdentifier(byteSid, 0);
然后,这取决于你拥有什么。如果用户正在运行您的应用程序(或通过您的网站/服务进行身份验证),则枚举令牌中的SID。例如,在桌面应用中使用WindowsIdentity.GetCurrent().Groups
。否则,您需要为该用户获取DirectoryEntry,然后获取像spoulson建议的tokenAttributes
属性:
DirectoryEntry deTargetUser = //target user;
DirectorySearcher dsTargetUser = new DirectorySearcher(deTargetUser);
dsTargetUser.SearchScope = SearchScope.Base; //tokenGroups is a constructed attribute, so have to ask for it while performing a search
dsTargetUser.Filter = "(objectClass=*)"; //this is closest thing I can find to an always true filter
dsTargetUser.PropertiesToLoad.Add("tokenGroups");
SearchResult srTargetUser = dsTargetUser.FindOne();
foreach(byte[] byteGroupSid in srTargetUser.Properties["tokenGroups"])
{
SecurityIdentifier groupSid = new SecurityIdentifier(byteGroupSid, 0);
if(groupSid == targetGroupSid)
{
//success
}
}
如果您需要从SID获取DirectoryEntry,您可以通过以下方式获取搜索字符串:
public static string GetSIDSearchFilter(SecurityIdentifier sid)
{
byte[] byteSid = new byte[sid.BinaryLength];
sid.GetBinaryForm(byteSid, 0);
return string.Format("(objectSid={0})", BuildFilterOctetString(byteSid));
}
public static string BuildFilterOctetString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
sb.AppendFormat("\\{0}", bytes[i].ToString("X2"));
}
return sb.ToString();
}
答案 6 :(得分:0)
我到这里来看看是否可以将“ LDAP://ldap.company.com:389 / ou = people,o = company”解析为 协议,端口,baseDN和服务器FQDN。我尝试了System.Uri类,它的工作方式与众不同。