【问题标题】:javascript regular expression for DNDN 的 javascript 正则表达式
【发布时间】:2012-02-15 07:19:31
【问题描述】:

我想要一个正则表达式来消除所有可能的 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

【问题讨论】:

  • 出于什么目的?如果 DN 格式不正确,LDAP 服务器会告诉您。
  • 用户将在表单中输入 DN。我想在客户端验证它。
  • 这对我来说似乎是问题的一部分。用户不应该从地下的洞中知道 LDAP DN。用户应输入唯一标识相关条目的内容,即 uid,然后您应搜索该条目。
  • 来吧,用户可以管理员。
  • 不能是基本DN吗?如果您了解 LDAP 连接,那么您应该承认这一点。也请只关注问题,即(DN 的正则表达式)。谢谢。

标签: javascript regex ldap dn


【解决方案1】:

我最近需要这个,所以我创建了一个完全遵循RFC-2253 的 LDAPv3 专有名称语法的。

属性类型

attributeType 可以用两种方式表示。以 alpha 开头的字母数字字符串,使用以下方法验证:

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

或者它可以是一个 OID,使用以下方法验证:

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

所以 attributeType 验证使用:

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

属性值

一个attributeValue 可以用3 种方式表示。一个十六进制字符串,它是一个以 # 开头的十六进制对序列。十六进制字符串验证使用:

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

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

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

或者一个带引号的字符串;该值以" 开头和结尾,并且可以包含除\" 之外的任何未转义字符。此外,可以使用上述转义字符串中的任何方法。引用字符串验证使用:

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

所有组合,attributeValue 验证使用:

#(?:[\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})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\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})*"))*)*$

Test it here

【讨论】:

  • 这太棒了!除了它不允许在事物之间使用空格,如第 5 页所述。我在名称组件之间的逗号后添加了\s*,并在名称组件内的等号两侧添加了\s*
  • @DuBistKomisch 你能详细说明你修复的第二部分吗? “并且在命名组件中的等号两侧。这只是分隔()的等号吗?
  • @JMIII 是的,我无法将最终的正则表达式放在评论字符限制中(否则我会首先发布它),但本质上是 )=( -> )\s*=\s*( in四个地方,除了一个,( -> ,\s*(
  • 如果我尝试使用上面的正则表达式并用单引号将它传递给 RegExp() 那么它会给出一个错误,理想情况下,它应该接受字符串正则表达式:错误:在新的地方没有重复正则表达式 () 在 :1:9
【解决方案2】:

这不仅不可能,而且永远不会奏效,甚至不应该尝试。 LDAP 数据(在这种情况下为专有名称)不是字符串。专有名称具有distinguishedName 语法,它不是字符串,并且必须使用目录服务器模式中定义的匹配规则进行比较。由于这个原因,正则表达式和本地语言比较、相对值和相等操作,如 perl 的 ~~eq== 以及 Java 的 == 不能与 LDAP 数据一起使用 - 如果程序员尝试这样做,出乎意料结果可能会发生并且代码是脆弱的、易碎的、不可预测的,并且不具有可重复的特性。不支持匹配规则的语言 LDAP API不能在需要比较、相等检查和相对值排序比较的 LDAP 中使用

例如,从 LDAP 的角度来看,可分辨名称“dc=example,dc=com”和“DC=example, DC=COM”在各个方面都是等效的,但本地语言相等运算符将返回 false

【讨论】:

  • 在所有 LDAP 方面都尊重可敬的 Terry Gardner,他指出的字符串比较问题是微不足道的,应该由任何称职的编码人员来解决。缩小比较的双方只是解决他给出的例子的一种方法。我不同意诸如“不可能”、“从不工作”、“不应该尝试”之类的语言。不过他的观点很好理解,DN 不是面向用户的,而是使用 RegEx 来解析它们,好吧,是谁说“现在你有两个问题”?
  • 根据MSDN documentation,DN 名称不能有任何前导或尾随空格,因此您的声明(dc=example,dc=comDC=example, DC=COM 是等效的)是错误的
【解决方案3】:

这对我有用:

表达式:

^(?<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 标准并限制允许的字符以完全匹配允许或不允许的字符。但我相信这是一个好的开始。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

    • 似乎不适用于此CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM
    • 我不确定为什么这个答案被接受,因为它甚至没有接近工作。 LDAP 值不必仅包含字母数字字符和下划线,因此\w+ 严重不足以匹配它们。 @Smitt 评论中的 DN 与正则表达式不匹配,仅仅是因为其中一个值包含一个空格,这不仅是允许的,而且非常常见。 [^,]+ 将是朝着正确方向迈出的一步,但请记住,有几个保留字符,它们都可以用 \ 转义。正则表达式必须考虑到这一点。
    • 顺便说一句,[,{1}] 似乎是多余的。为什么需要为单个字符创建括号集?就此而言,为什么你需要{1},当它后面跟着不匹配逗号的东西时?您可以用, 替换所有这些,而无需对正则表达式进行任何实际更改。
    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    相关资源
    最近更新 更多