2011-10-07 42 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); 
}