在.NET中,是否有一个API可以解析rfc-2253编码的可区分名称(Distinguished Name)中的CN信息?我知道有一些第三方库可以做到这一点,但如果可能的话,我更愿意使用原生的.NET库。
下面是一些字符串编码的DN示例:
CN=L. Eagle,O=Sue\, Grabbit and Runn,C=GB
CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM
在.NET中,是否有一个API可以解析rfc-2253编码的可区分名称(Distinguished Name)中的CN信息?我知道有一些第三方库可以做到这一点,但如果可能的话,我更愿意使用原生的.NET库。
下面是一些字符串编码的DN示例:
CN=L. Eagle,O=Sue\, Grabbit and Runn,C=GB
CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM
X509Certificate2
,则有一种方法可用于提取简单名称。简单名称等同于主证书的主题字段中的公共名称 RDN:x5092Cert.GetNameInfo(X509NameType.SimpleName, false);
或者,如果存在的话,可以使用X509NameType.DnsName
来检索主题备用名称;否则,它将默认为通用名称:
x5092Cert.GetNameInfo(X509NameType.DnsName, false);
DNS Name=prog.org
,此方法将返回 prog.org
。 - Pylyp LebedievX509NameType.SimpleName
来表示CN。 - digital_jedistring 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
cn=Robert Smith+uid=rsmith,ou=people,dc=example,dc=com
。这会导致“指定的可分辨名称格式无效”的错误。 - Nathanial WoollsGetDNComponents
的代码在这里:https://github.com/dotnet/corefx/blob/c539d6c627b169d45f0b4cf1826b560cd0862abe/src/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Utils.cs#L440-L449 - Cameron TaggartSystem.DirectoryServices.ActiveDirectory.Component[]
是内部的。Console.WriteLine("Tipo: " + test.GetType().FullName);
- Kiquenet当我发现你提出的问题时,我自己也有同样的疑问。在BCL中没有找到任何内容;但是,我偶然发现了这篇CodeProject文章,它完全击中了要害。
我希望它也能帮助到你。
http://www.codeproject.com/Articles/9788/An-RFC-2253-Compliant-Distinguished-Name-Parser
var distinguishedName= new X500DistinguishedName("CN=TestGroup,OU=Groups,OU=UT-SLC,OU=US,DC=Company,DC=com");
var commonNameData = new AsnEncodedData("CN", distinguishedName.RawData);
var commonName = commonNameData.Format(false);
Win32函数算吗?你可以使用PInvoke与DsGetRdnW
一起使用。有关代码,请参见我对另一个问题的回答:https://dev59.com/i0nSa4cB1Zd3GeqPNWFu#11091804。
在这里,我想要添加一点意见。如果你先了解业务规则,并确定最终将在公司实施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);
}
CN=Usuarios del dominio,CN=Users,DC=company,DC=es
,CN=PRE_VPN_Usuarios,CN=Users,OU=PREPRODUCCION,DC=company,DC=es
,CN=PRE_Usuarios COMUNICADOS MAD,CN=Users,OU=PREPRODUCCION,DC=company,DC=es
,CN=PRE_Campaña TELEFONICA Agentes MAD,OU=TELEFONICA,OU=CAMPAÑAS,OU=PREPRODUCCION,DC=company,DC=es
。 - Kiquenetstring 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;
}
CN=Usuarios del dominio,CN=Users,DC=company,DC=es
, CN=PRE_VPN_Usuarios,CN=Users,OU=PREPRODUCCION,DC=company,DC=es
, CN=PRE_Usuarios COMUNICADOS MAD,CN=Users,OU=PREPRODUCCION,DC=company,DC=es
,CN=PRE_Campaña TELEFONICA Agentes MAD,OU=TELEFONICA,OU=CAMPAÑAS,OU=PREPRODUCCION,DC=company,DC=es
。 - Kiquenet(?:^|,\s?) <-- Start or a comma
(?:
(?<name>[A-Z]+)
=
(?<val>
"(?:[^"]|"")+" <-- Quoted strings
|
(?:\\,|[^,])+ <-- Unquoted strings
)
)+
name
和val
捕获组。"Hello"
),这允许它们包含未转义的逗号。或者,如果没有引号,逗号必须用反斜杠转义(例如Hello\, there!
)。此正则表达式处理带引号和不带引号的字符串。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=Martin Luther King\, Jr.
会不正确地返回 Martin Luther King
。 - Eric Eskildsen