2018-02-11

LDAP Basics

LDAP [1] 在現在 IT 系統應用中,幾乎快變成「計概」等級的基礎服務,但是聽過的人多,知道用途的人可能也不少,但是能明確知道應用場域跟侷限的人就不多了;甚至很多人只是看著操作說明,一步步設定起來,對於基礎名詞處於一知半解。

LDAP 顧名思義,它是脫胎自 Directory Access Protocol (DAP;定義於 X.500 [2],a.k.a ISO/IEC 9594-1),最早可追溯到 1990 的版本 [3],幾乎所有基本名詞都在 X.500 就定義好了,這邊整理我認為最重要的三個基本名詞。

ObjectClass
在 LDAP 中,每一筆看到的資料 (entry),舉凡人員或組織,都是一堆屬性 (attribute) 的組合,而個別 entry 必須定義那些屬性?可以擁有那些屬性?則由該 entry 所擁有的 objectclass 決定。(objectclass 本身也是 entry 的屬性之一,特別的是這個屬性是預設必要的,用這個設定值來控制是否帶入其他屬性。)

如同 object-oriented programming 一樣,這邊的 class 裡頭會定義 instance (也就是前述的 entry) 擁有的 fields (前述的 attribute);classes 之間也有繼承關係,可以讓 sub-classes 直接繼承 base class 的所有 attributes 而不用重複宣告。相對於 OOP 中的 extends,這邊繼承時使用的關鍵字是 SUP,如果單純作為 LDAP 使用者不看 LDIF 對 objectclass 定義的話,可能不會接觸這個詞。

不一樣的是:ObjectClass 中並不定義行為 (methods),也沒有 constructor;因此當定義 entry 時,採直接描述 entry 的各個屬性,包括 objectclass 與 attribute。底下是一個 displayname 為 /QNAP 的 organization entry:
dn: O=QNAP
objectclass: organization
objectclass: top
displayname: /QNAP
其中 objectclass 欄位即這個 entry 擁有的「型別」,一個 entry 可以同時擁有多個 objectclass 屬性;但 ObjectClass 底下細分成 ABSTRACT, AUXILIARYSTRUCTURAL 三種,一個 entry 同時間只能有一個 objectclass 屬性為 STRUCTURAL,類似 OOP 中做為 initiate 的 concrete class。

Inheritance of ObjectClass

至於 AUXILIARY 則跟 OOP 中的 interface 類似,用於讓 entry 帶上需要的屬性,而 ABSTRACT 則類似 root interface 或是 Java 中 Object 這個 class。ABSTRACT ObjectClass 一般不會自行定義,僅沿用系統中預帶的 top ABSTRACT ObjectClass。

AttributeType
相對於 ObjectClass 定義 compound type 的結構,AttributeType 可視為用於定義 scalar type。注意:LDAP 的所有 ObjectClasses 都只能是單層結構,不允許擁有型別為其他 compound type 的 fields。

此外,AttributeType 的定義中會指明套用的 equality rule,類似於 OOP class 中常實作的 equals() method。如同 ObjectClass,AttributeType 也可以繼承其他的 AttributeType,用於直接延用 base attribute 的 equality rule。

MatchingRule
即前述 equality rule 的實作,常見的有:
  • caseExactIA5Match
  • caseIgnoreMatch, caseIgnoreIA5Match, caseIgnoreListMatch
  • distinguishedNameMatch
  • facsimileTelephoneNumber, integerMatch, telephoneNumberMatch 等。

了解這三個幾本名詞後,下一步就能對 LDAP 中如何依賴 distinguish name (DN) 定位一個 entry,以及 entries 如何形成 directory information tree (DIT) 樹狀結構進行了解了。

see also:
[1] Wikipedia: LDAP
[2] Wikipedia: X.500
[3] ISO/IEC 9594-1:1990
[4] Understanding the LDAP Protocol, Data Hierarchy, and Entry Components
[5] LdapWiki.com

2018-02-07

C# URL Encoding (Con't)

前一篇 [1] 提到當使用 URL 傳參數遇到一些特殊字元時,.NET framework 提供了幾種編碼方式都不能完整處理,需要另行寫一段轉換程式,將參數另行處理,甚至需要將 IIS 的 allowDoubleEscaping 打開方能順利執行。

為了避免掙扎於 IIS 安全機制與參數編碼難以兩全的問題,同事幫忙找到在編寫轉換程式時可以使用 HttpServerUtility.UrlTokenEncode() 處理參數;雖然還是得自己寫一段程式,但可以不用更改 IIS 設定。本質上這個編碼接近 Base64 [2],但是因為原始 Base64 仍會生成某些特殊字元 (+, /, =),因此這裡等於是 Base64 的變種。

關於這三個 class 與 .NET framework 版本的關係,稍微整理了一下:
Class Name.NET Framework.NET Core
System.Web.HttpServerUtility1.1N/A
System.Web.HttpUtility1.12.0
System.Uri1.11.0

附帶一提:微軟推出新版的 API Browser,將原先在 MSDN 上的 API 文件改放到 docs.microsoft.com;新版的站台提供較多有關 .NET Core 或 PCL 版本的資訊,但也捨棄了 .NET framework 4.5 以前的資訊,因此查不到各別 class 起源於哪個版本的 .NET framework。

see also:
[1] C# URL Encoding
[2] Wikipedia: Base64
[3] HttpServerUtility: MSDN, docs.microsoft.com
[4] HttpUtility: MSDN, docs.microsoft.com
[5] Uri: MSDN, docs.microsoft.com