あけましておめでとうございます。 仕事中にさぼって書いています。
LDAP サーバーを利用するコードを Java で書くとしたら, たぶん JNDI を利用するケースが多いんだろうなと思います。 とはいえ, JNDI 自体は LDAP の取り扱いに特化した API というわけではありませんので, そうとは気づかずにさわりはじめると, 最初のうちは戸惑います。 たとえば DirContext
の bind
とか unbind
とかのメソッドは, LDAP における BIND や UNBIND とはまったく別の意味を持っています。 また, JNDI を使って LDAP 関連のコードを書こうとすると, Hashtable
とか Enumeration
とかが視界に入ってくるというのも, やや苦しいところです。
そもそも, JNDI 以外の LDAP 用のクライアントライブラリには, どんなものがあるでしょう。 今回, Apache Directory LDAP API と UnboundID LDAP SDK for Java を, 少しだけさわってみました。
Apache Directory LDAP API
Apache Directory LDAP API は, 依存する外部ライブラリが少なくないのが, やや気になるところです。 ログのために SLF4J を, NIO のために Apache MINA を, そのほか Commons 何々などなどを利用しているので, クラスパスに置く必要のある JAR ファイルがやや多くなってしまいます。 ただ, 少しさわってみたうえでの第一印象としては, ドキュメント がわかりやすく書かれており, まずまず使いやすそうに見えました。
最も単純な BIND および UNBIND をやってみます。 LDAP サーバーと接続を開き, BIND をおこない, UNBIND をおこない, そして接続を閉じるというものです。
LdapConnection conn = new LdapNetworkConnection("192.168.1.1", 389); try { conn.connect(); conn.bind("cn=Manager,dc=localdomain", "secret"); conn.unBind(); } catch (LdapException e) { // ... } finally { try { conn.close(); } catch (IOException e) { // .... } }
connect
メソッドで接続を開き, bind
メソッドで BIND をおこない, unBind
メソッドで UNBIND をおこない, そして close
メソッドで接続を閉じます。 非常に直感的でわかりやすいと感じます。 ちなみに, もし匿名バインドをおこないたいなら,
conn.bind("", "");
もしくは,
conn.bind();
と書くことができます。
ところで, ソースコードを眺めてみますと, bind
メソッドは, もしまだ接続が開かれていなければ, まず内部で connect
メソッドを呼び出しているようですので, 上記のコードでは connect
メソッドの呼び出しを省略しても構わないかもしれません。 それに対して, unBind
メソッドは, UNBIND リクエストを LDAP サーバーに送った後に接続を閉じるということ (FIN
を送って ACK
を受け取ること) をおこなってはいますが, close
メソッドと同じことをすべておこなっているわけではなく, 使用済みソケットを廃棄するところまではおこなっていないように見えなくもないので, 上記のコードで close
メソッドの呼び出しを省略してよいものかどうか, ちょっとよくわかりません。
なお, 各メソッドのうち, close
メソッドは IOException
をスローする可能性があり, それ以外は LdapException
をスローする可能性があります。 LdapException
のサブクラスには LdapOperationException
というものがあり, そこには getResolvedDn
と getResultCode
というメソッドが定義されていますので, BIND などのオペレーションの結果に応じていろいろ処理を分岐する必要がある場合に, ちょっと便利かもしれません。
UnboundID LDAP SDK for Java
UnboundID LDAP SDK for Java は, 依存する外部ライブラリが特になく, その点は Apache Directory LDAP API よりもデリバリーしやすいと言えるかもしれません。 ドキュメント は, LDAP というプロトコル自体について幅広く知っていないとやや理解が難しいんじゃないかという印象を持ちました。 (というか, 自分自分の読解力不足を棚に上げて, そういう言い訳をしたいだけだったりもしますけれど。) それから, ログは JUL (java.util.logging
) を利用しているようです。
それでは, こちらも単純な BIND および UNBIND をやってみましょうか。 次のようになりました。
LDAPConnection conn = null; try { conn = new LDAPConnection("192.168.1.1", 389); conn.bind("cn=Manager,dc=localdomain", "secret"); } catch (LDAPException e) { // ... } finally { if (conn != null) conn.close(); }
LDAPConnection
インスタンスを作成する段階で LDAP サーバーとの接続を開くことがおこなわれ, また close
メソッドで接続を閉じる際には UNBIND もあわせておこなわれますので, Apache Directory LDAP API に比べれば, さらにコードはコンパクトになっています。 ちなみに, 匿名バインドをおこないたいなら,
conn.bind("", "");
と書くことができます。
Apache Directory LDAP API と違って IOException
を気にする必要がないというのは, ちょっとうれしい気もします。 また, LDAPException
には, getMatchedDN
や getResultCode
だけでなく, いくつか便利そうなメソッドが定義されています。 Apache Directory LDAP API の LdapException
(というか, そのサブクラスの LdapOperationException
) は, JNDI の NamingException
と同様にエラーコードに応じて多数のサブクラスを用意するというアプローチですが, UnboundID LDAP SDK for Java の LDAPException
は, あまりサブクラスを増やさず, なるべくこのクラスだけでいろいろなことを扱うことにするというアプローチのようです。
感想
たまたま, ぜんぜん別の話題を探しているときに, LDAP Java library - Stack Overflow (Dec 23, 2008) という投稿を見かけたのが, 今回のきっかけでした。 まだ, BIND と UNBIND しかやっていなくて, どちらがいいかというのは全く言えませんが, 入門レベルで取り付きやすそうなのは Apache のほうで, より高度なことを期待するなら UnboundID といったところなのでしょうか。
No comments:
Post a Comment