2011-10-07 28 views
10

¿Hay una llamada en .NET que analiza el CN ​​desde un nombre completo codificado rfc-2253? Sé que hay algunas bibliotecas de terceros que hacen esto, pero preferiría usar bibliotecas .NET nativas, si es posible.Extracto Nombre común de nombre completo

Ejemplos de una cadena codificada DN

CN = L. Ventas águila, O = Sue \, Grabbit y Runn, C = GB

CN = Jeff Smith, OU = DC = Fabrikam, DC = COM

+0

Es posible que desee agregar LDAP a la lista de etiquetas de su pregunta. Además, busque SO para [LDAP C#]. Puede haber una pregunta relacionada. –

+0

Gracias @Jim Mischel – FunLovinCoder

+0

Consulte https://pscx.codeplex.com/SourceControl/latest#Trunk/Src/Pscx.UnitTests/DirectoryServices/DirectoryServicesTest.cs para ver el código utilizado en las extensiones de la comunidad Powershell –

Respuesta

0

Podría no sólo recuperar el atributo CN valores?

Como nota correctamente, utiliza la clase de otra persona, ya que hay muchos casos de bordes divertidos (comas escapadas, otros caracteres escapados) que hacen que el análisis de un DN parezca fácil, pero realmente bastante complicado.

Normalmente uso una clase de Java que viene con Novell (ahora NetID) Identity Manager. Entonces eso no es útil.

+0

No se puede obtener el atributo valor de una entrada LDAP: solo tiene que trabajar con el certificado. Gracias de cualquier manera. – FunLovinCoder

+0

@swisstony: Ah, usted tiene un certificado DN. Ese sigue siendo el mismo problema básico, de análisis apropiado. – geoffc

+0

Sí, sigue siendo un DN tan mismo problema. Parece que tengo que usar una biblioteca de terceros como bouncycastle ... – FunLovinCoder

5

Tuve la misma pregunta, cuando encontré la tuya. No encontré nada en el BCL; sin embargo, tropecé con este artículo de CodeProject que golpeó la uña directamente en la cabeza.

Espero que te ayude también.

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

+3

Acabo de lanzarlo como un paquete NuGet aquí: https://www.nuget.org/packages/DNParser/ (solo para ser claro: I no soy el autor, pero me encantan los paquetes NuGet). – picrap

4

Después de buscar en el código fuente .NET parece que hay una clase de utilidad interna que puede parse Distinguished Names en sus diferentes componentes. Por desgracia, la clase de utilidad no es pública, pero se puede acceder a él mediante la reflexión:

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 

Los resultados se vería así:

//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 

Por favor, no esto es una clase de utilidad interior y podrían cambiar en una versión futura.

+0

+1 Gran hallazgo. ¿Por qué siguen haciendo interno el código útil? – i3arnon

+0

Funcionó muy bien hasta que necesité analizar RDN multivalor. por ejemplo '' 'cn = Robert Smith + uid = rsmith, ou = personas, dc = ejemplo, dc = com'''. Esto falla con "El nombre completo especificado tiene un formato no válido". –

-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

Las piezas RDN pueden contener comas escapadas en forma '\,', por lo que su división inicial no funciona. También puede haber espacios entre las partes que debe eliminar. – picrap

2

Si está trabajando con un X509Certificate2, hay un método nativo que puede usar para extraer el nombre DNS. El nombre DNS es normalmente equivalente a la RDN Nombre Común en el campo Asunto del certificado principal:

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

Simplemente añadiendo mi granito de arena aquí. Esta implementación funciona "mejor" si primero se enteran de cuáles son las reglas comerciales que finalmente dictarán cuánto del RFC se implementará alguna vez en su empresa.

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); 
} 
Cuestiones relacionadas