.NET中是否存在一个从rfc-2253编码可分辨名称解析CN的调用?我知道有一些第三方库可以做到这一点,但如果可能的话,我宁愿使用本地.NET库。字符串的从可分辨名称中提取公用名称
实例编码DN
CN = L。鹰,O =苏\,Grabbit和银行经营,C = GB
CN =杰夫·史密斯,OU =销售额,DC = Fabrikam的,DC = COM
.NET中是否存在一个从rfc-2253编码可分辨名称解析CN的调用?我知道有一些第三方库可以做到这一点,但如果可能的话,我宁愿使用本地.NET库。字符串的从可分辨名称中提取公用名称
实例编码DN
CN = L。鹰,O =苏\,Grabbit和银行经营,C = GB
CN =杰夫·史密斯,OU =销售额,DC = Fabrikam的,DC = COM
难道你不只是取回CN属性值?
正如你正确地指出,使用别人的类,因为有很多有趣的边缘案例(逃脱的逗号,转义其他字符),使解析DN看起来很容易,但实际上相当棘手。
我通常使用Novell(Now NetID)Identity Manager附带的Java类。所以这没有帮助。
否无法获取属性来自LDAP条目的值 - 只需拥有证书即可使用。不管怎么说,还是要谢谢你。 – FunLovinCoder
@swisstony:啊,你有一个证书DN。这仍然是正确解析的基本问题。 – geoffc
是的,仍然是DN同样的问题。这看起来像我可能不得不使用第三方库,如bouncycastle ... – FunLovinCoder
当我找到你的时候,我自己也有同样的问题。 BCL没有找到任何东西;不过,我偶然发现了这个CodeProject上的文章,它直接击中了头部。
我希望它也能帮助你。
http://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser
我刚刚发布它作为一个NuGet包在这里:https://www.nuget.org/packages/DNParser/(只是要清楚:我我不是作者,但我喜欢NuGet包)。 – picrap
Win32的函数是否计数?您可以通过DsGetRdnW
使用PInvoke。有关代码,请参阅我对另一个问题的回答:https://stackoverflow.com/a/11091804/628981。
在.NET源代码中寻找它后,它看起来像有一个内部实用程序类,它可以将parse Distinguished Names集成到它们的不同组件中。不幸的是,实用类是不公开的,但你可以使用反射访问:
string dn = "CN=TestGroup,OU=Groups,OU=UT-SLC,OU=US,DC=Company,DC=com";
Assembly dirsvc = Assembly.Load("System.DirectoryServices");
Type asmType = dirsvc.GetType("System.DirectoryServices.ActiveDirectory.Utils");
MethodInfo mi = asmType.GetMethod("GetDNComponents", BindingFlags.NonPublic | BindingFlags.Static);
string[] parameters = { dn };
var test = mi.Invoke(null, parameters);
//test.Dump("test1");//shows details when using Linqpad
//Convert Distinguished Name (DN) to Relative Distinguished Names (RDN)
MethodInfo mi2 = asmType.GetMethod("GetRdnFromDN", BindingFlags.NonPublic | BindingFlags.Static);
var test2 = mi2.Invoke(null, parameters);
//test2.Dump("test2");//shows details when using Linqpad
结果是这样的:
//test1 is array of internal "Component" struct that has name/values as strings
Name Value
CN TestGroup
OU Groups
OU UT-SLC
OU US
DC company
DC com
//test2 is a string with CN=RDN
CN=TestGroup
请不这是一个内部实用工具类,并可能改变未来版本。
+1大发现。为什么他们不断制作有用的代码? – i3arnon
工作得很好,直到我需要解析多值RDN。例如'''cn = Robert Smith + uid = rsmith,ou = people,dc = example,dc = com'''。 “指定的专有名称的格式无效”失败。 –
using System.Linq;
var dn = "CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM";
var cn = dn.Split(',').Where(i => i.Contains("CN=")).Select(i => i.Replace("CN=", "")).FirstOrDefault();
RDN部分可以包含'\,'形式的转义逗号,因此您的初始分割不起作用。另外,您必须删除部件之间的空间。 – picrap
这个怎么样:
string cnPattern = @"^CN=(?<cn>.+?)(?<!\\),";
string dn = @"CN=Doe\, John,OU=My OU,DC=domain,DC=com";
Regex re = new Regex(cnPattern);
Match m = re.Match(dn);
if (m.Success)
{
// Item with index 1 returns the first group match.
string cn = m.Groups[1].Value;
}
从Powershell Regular Expression for Extracting Parts of an Active Directory Distiniguished Name改编。
如果您使用的是X509Certificate2,则可以使用本地方法来提取DNS名称。 DNS名称通常相当于通用名RDN的主要证书的主题领域内:
x5092Cert.GetNameInfo(X509NameType.DnsName, false);
这里只是将我的两分钱。如果您首先了解哪些业务规则已到位,并且最终将决定您的公司将实施多少个RFC,那么此实现“最佳”。
private static string ExtractCN(string distinguishedName)
{
// CN=...,OU=...,OU=...,DC=...,DC=...
string[] parts;
parts = distinguishedName.Split(new[] { ",DC=" }, StringSplitOptions.None);
var dc = parts.Skip(1);
parts = parts[0].Split(new[] { ",OU=" }, StringSplitOptions.None);
var ou = parts.Skip(1);
parts = parts[0].Split(new[] { ",CN=" }, StringSplitOptions.None);
var cnMulti = parts.Skip(1);
var cn = parts[0];
if (!Regex.IsMatch(cn, "^CN="))
throw new CustomException(string.Format("Unable to parse distinguishedName for commonName ({0})", distinguishedName));
return Regex.Replace(cn, "^CN=", string.Empty);
}
您可能希望将LDAP添加到问题标签列表中。另外,搜索[LDAP C#]。可能有一个相关的问题。 –
谢谢@Jim Mischel – FunLovinCoder
请参阅https://pscx.codeplex.com/SourceControl/latest#Trunk/Src/Pscx.UnitTests/DirectoryServices/DirectoryServicesTest.cs了解Powershell社区扩展中使用的代码 –