是否在.NET中调用从rfc-2253编码的专有名称解析CN?我知道有一些第三方库可以做到这一点,但我更愿意使用本机.NET库。
字符串编码DN的示例
CN = L。 Eagle,O = Sue \,Grabbit和Runn,C = GB
CN = Jeff Smith,OU =销售额,DC = Fabrikam,DC = COM
是否在.NET中调用从rfc-2253编码的专有名称解析CN?我知道有一些第三方库可以做到这一点,但我更愿意使用本机.NET库。
字符串编码DN的示例
CN = L。 Eagle,O = Sue \,Grabbit和Runn,C = GB
CN = Jeff Smith,OU =销售额,DC = Fabrikam,DC = COM
当我找到你的时候,我自己也有同样的问题。在BCL没找到任何东西;但是,我偶然发现了这篇CodeProject的文章,这篇文章正好击中了头部。
我希望它也会帮助你。
http://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser
如果您使用的是X509Certificate2,则可以使用本机方法提取DNS名称。 DNS名称通常等效于主证书的“主题”字段中的公用名称RDN:
x5092Cert.GetNameInfo(X509NameType.DnsName, false);
在浏览.NET源代码之后,看起来有一个内部实用程序类可以 解析专有名称 他们的不同组成部分。遗憾的是,实用程序类未公开,但您可以使用反射访问它:
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
请注意,这不是内部实用程序类,可能会在将来的版本中更改。
Win32功能有效吗?您可以使用PInvoke DsGetRdnW
。有关代码,请参阅我对其他问题的回答: https://stackoverflow.com/a/11091804/628981。
在这里加我的两分钱。如果您首先了解最终将要执行的业务规则,那么此实现将“最佳” 多少 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);
}
如果订单不确定,我这样做:
private static string ExtractCN(string dn)
{
string[] parts = dn.Split(new char[] { ',' });
for (int i = 0; i < parts.Length; i++)
{
var p = parts[i];
var elems = p.Split(new char[] { '=' });
var t = elems[0].Trim().ToUpper();
var v = elems[1].Trim();
if (t == "CN")
{
return v;
}
}
return null;
}
你能不能只检索CN属性值?
正如你正确指出的那样,使用其他人的类,因为有很多有趣的边缘情况(转义逗号,转义其他字符),这使得解析DN看起来很容易,但实际上相当棘手。
我通常使用Novell(Now NetID)Identity Manager附带的Java类。所以这没有用。
这个怎么样:
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;
}