JavaScript正则表达式用于DN

8

我希望你能翻译一个正则表达式,以验证所有可能的DN(区分名)类型。

我创建了一个正则表达式,但它并不是很好。

/([A-z0-9=]{1}[A-z0-9]{1})*[,??]/其他一些修改后,但都没有成功。

可能的DN可以是:

CN=abcd,CN=abcd,O=abcd,C=us
CN=abcd0520,CN=users,O=abcd,C=us
C=us

etc

为了什么目的?LDAP服务器会告诉您DN是否格式不正确。 - user207421
这对我来说似乎是问题的一部分。用户不应该把LDAP DN和地洞混为一谈。用户应该输入某些唯一标识条目的内容,例如uid,然后您应该搜索该条目。 - user207421
1
来吧,用户可以成为管理员。 - Muhammad Imran Tariq
我再次强调,用户或管理员应输入搜索表达式以查找所需的LDAP条目。或者,验证工作应留给LDAP服务器。你不需要解决这个无关紧要的问题。 - user207421
2
它不能是基本DN吗?如果您了解LDAP连接,则应该承认。另外,请专注于问题,即(DN的正则表达式)。谢谢。 - Muhammad Imran Tariq
显示剩余2条评论
4个回答

16

我最近有这方面的需求,所以我创建了一个完美遵循LDAPv3可分辨名称语法规则的工具,该规则在RFC-2253中定义。

属性类型

属性类型可以通过两种方式表达。以字母开头的字母数字字符串,使用以下验证:

[A-Za-z][\w-]*

或者它可以是OID,使用以下验证:

\d+(?:\.\d+)*

因此,属性类型使用以下验证:

[A-Za-z][\w-]*|\d+(?:\.\d+)*

属性值

属性值可以通过三种方式表达。十六进制字符串,它是具有前导#的十六进制对序列。 十六进制字符串使用以下验证:

#(?:[\dA-Fa-f]{2})+

或转义字符串;每个非特殊字符“按原样”表示(使用[^,=\+<>#;\\"]进行验证)。 特殊字符可以以前导符\表示(使用\\[,=\+<>#;\\"]进行验证)。 最后,任何字符都可以以带前导符\的十六进制对表示(使用\\[\dA-Fa-f]{2}进行验证)。 转义字符串使用以下验证:

(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*

或引用字符串;该值以"开头和结尾,并且可以包含任何未转义的字符,除了\"。 此外,可以使用上面从转义字符串中的任何方法。 引用字符串使用以下验证:

"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"

所有组合起来,属性值使用以下验证:

#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"

名称组件

BNF中的名称组件为:

name-component = attributeTypeAndValue *("+" attributeTypeAndValue)
attributeTypeAndValue = attributeType "=" attributeValue

在正则表达式中:

(?#attributeType)=(?#attributeValue)(?:\+(?#attributeType)=(?#attributeValue))*

(?#attributeType)(?#attributeValue) 占位符替换为上面的值,得到以下结果:

(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"))*

这会验证单个名称部件。

可分辨名称

最终,可分辨名称的 BNF 格式为:

name-component *("," name-component)

在正则表达式中:

(?#name-component)(?:,(?#name-component))*

将 (?#name-component) 占位符替换为上面的值,得到以下结果:

^(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<<>gt;#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"))*(?:,(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"))*)*$

在这里测试


1
这很棒!除了它不允许在事物之间有空格,就像第5页上提到的那样。我在name-component逗号后面添加了\s*,并在name-component内部等号的两侧添加了它。 - DuBistKomisch
@DuBistKomisch,你能详细说明一下你用来修复的第二部分吗?“以及在命名组件中等号符号的两侧。这只是将()分隔开的等号符号吗? - JMIII
1
@JMIII 是的,我无法在评论字符限制中放入最终正则表达式(否则我一开始就会直接发布它),但本质上 )=( 在四个位置变成了 )\s*=\s*(,另外还有一个 ,( 变成了 ,\s*( - DuBistKomisch
如果我尝试使用上面的正则表达式,并将其带有单引号的字符串传递给RegExp(),那么它会出现错误,理论上它应该接受字符串正则表达式:错误:无内容可重复,位于new RegExp (<anonymous>) at <anonymous>:1:9。 - Prashant Biradar

2
这不仅是不可能的,而且永远不会起作用,甚至不应该尝试。LDAP数据(在本例中为专有名称)不是字符串。专有名称具有“distinguishedName”语法,这不是字符串,并且必须使用目录服务器模式中定义的匹配规则进行比较。因此,正则表达式和本地语言比较、相对值和等式操作,例如perl的“~~”,“eq”和“==”以及Java的“==”不能与LDAP数据一起使用 - 如果程序员尝试这样做,则可能会出现意外结果,并且代码是脆弱的、不可预测的,并且没有可重复的特征。在LDAP需要比较、相等检查和相对值排序比较时,不支持匹配规则的语言LDAP API不可用。
例如,“dc=example,dc=com”和“DC=example,DC=COM”的专有名称在LDAP方面完全相同,但本地语言等式运算符将返回false。

尊重Terry Gardner在LDAP方面的专业知识,他指出的字符串比较问题是微不足道的,任何有能力的编码人员都应该考虑到这一点。将比较的两侧转换为小写字母只是解决他提出的示例的一种方法。我不同意使用“不可能”,“永远不会起作用”,“不应尝试”的语言。尽管如此,他的观点很好,DN不是用户界面,使用RegEx来解析它们,嗯,谁说过,“现在你有两个问题了”? - Dave Sims
根据MSDN文档,DN名称不能有任何前导或尾随空格,因此您的语句(dc=example,dc=comDC=example, DC=COM是等效的)是错误的。 - kpull1

0

这对我有用:

表达式:

^(?<RDN>(?<Key>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?<Value>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+))(?:\s*\,\s*(?<RDN>(?<Key>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?<Value>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)))*$

测试:

CN=Test User Delete\0ADEL:c1104f63-0389-4d25-8e03-822a5c3616bc,CN=Deleted Objects,DC=test,DC=domain,DC=local

该表达式已经进行了正则表达式转义,为了避免在C#中重复所有反斜杠,请确保在字符串前面加上未转义的字面量@符号,即

var dnExpression = @"...";

这将产生四个组,第一个是整个字符串的副本,第二个是最后一个RDN的副本,第三和第四个是键/值对。您可以使用每个组的Captures集合来索引每个键/值。

您还可以使用此方法通过将表达式裁剪到通常的“^... $”所包围的“(?...)”组来验证RDN以要求完整值(字符串的开始-结束)。

我允许十六进制特殊字符转义“\”,简单字符转义“\”或除“,\”之外的任何其他内容在键/值 DN文本中。我猜想通过花费额外的时间浏览MSDN AD标准并限制允许的字符以精确匹配允许或不允许的内容,可以完善此表达式。但我认为这是一个很好的开始。


-1

我创建了一个。工作得很好。

^(\w+[=]{1}\w+)([,{1}]\w+[=]{1}\w+)*$

1
似乎无法与此 CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM 一起使用。 - Smitt
2
我不确定为什么这个答案被接受了,因为它根本不能正常工作。LDAP值不必只由字母数字字符和下划线组成,因此\w+对于匹配它们来说是非常不足的。@Smitt评论中的DN之所以不匹配正则表达式,仅仅是因为其中一个值包含了一个空格,这不仅是允许的,而且非常普遍。[^,]+是朝着正确方向迈出的一步,但请记住,有几个保留字符,所有这些字符都可以用\进行转义。正则表达式必须考虑到这一点。 - Adi Inbar
顺便说一下, [,{1}] 看起来多余了。为什么需要为一个单字符创建括号集合?而且,在后面跟着的东西不匹配逗号,为什么还需要 {1}?删除所有这些内容并使用 , 替换即可,在正则表达式中没有实际变化。 - Adi Inbar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接