2011-10-07 51 views
10

.NET中是否存在一个从rfc-2253编码可分辨名称解析CN的调用?我知道有一些第三方库可以做到这一点,但如果可能的话,我宁愿使用本地.NET库。字符串的从可分辨名称中提取公用名称

实例编码DN

CN = L。鹰,O =苏\,Grabbit和银行经营,C = GB

CN =杰夫·史密斯,OU =销售额,DC = Fabrikam的,DC = COM

+0

您可能希望将LDAP添加到问题标签列表中。另外,搜索[LDAP C#]。可能有一个相关的问题。 –

+0

谢谢@Jim Mischel – FunLovinCoder

+0

请参阅https://pscx.codeplex.com/SourceControl/latest#Trunk/Src/Pscx.UnitTests/DirectoryServices/DirectoryServicesTest.cs了解Powershell社区扩展中使用的代码 –

回答

0

难道你不只是取回CN属性值?

正如你正确地指出,使用别人的类,因为有很多有趣的边缘案例(逃脱的逗号,转义其他字符),使解析DN看起来很容易,但实际上相当棘手。

我通常使用Novell(Now NetID)Identity Manager附带的Java类。所以这没有帮助。

+0

否无法获取属性来自LDAP条目的值 - 只需拥有证书即可使用。不管怎么说,还是要谢谢你。 – FunLovinCoder

+0

@swisstony:啊,你有一个证书DN。这仍然是正确解析的基本问题。 – geoffc

+0

是的,仍然是DN同样的问题。这看起来像我可能不得不使用第三方库,如bouncycastle ... – FunLovinCoder

5

当我找到你的时候,我自己也有同样的问题。 BCL没有找到任何东西;不过,我偶然发现了这个CodeProject上的文章,它直接击中了头部。

我希望它也能帮助你。

http://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser

+3

我刚刚发布它作为一个NuGet包在这里:https://www.nuget.org/packages/DNParser/(只是要清楚:我我不是作者,但我喜欢NuGet包)。 – picrap

4

在.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 

请不这是一个内部实用工具类,并可能改变未来版本。

+0

+1大发现。为什么他们不断制作有用的代码? – i3arnon

+0

工作得很好,直到我需要解析多值RDN。例如'''cn = Robert Smith + uid = rsmith,ou = people,dc = example,dc = com'''。 “指定的专有名称的格式无效”失败。 –

-2
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(); 
+2

RDN部分可以包含'\,'形式的转义逗号,因此您的初始分割不起作用。另外,您必须删除部件之间的空间。 – picrap

2

如果您使用的是X509Certificate2,则可以使用本地方法来提取DNS名称。 DNS名称通常相当于通用名RDN的主要证书的主题领域内:

x5092Cert.GetNameInfo(X509NameType.DnsName, false); 
1

这里只是将我的两分钱。如果您首先了解哪些业务规则已到位,并且最终将决定您的公司将实施多少个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); 
}