Your SlideShare is downloading. ×
  • Like
Ruby で扱う LDAP のススメ
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Ruby で扱う LDAP のススメ

  • 14,049 views
Published

RubyKaigi2010 企画 ”Ruby で扱う LDAP のススメ”資料です。 …

RubyKaigi2010 企画 ”Ruby で扱う LDAP のススメ”資料です。

数例ある事例紹介の内、谷口さんの事例紹介のスライドは以下にあります
http://www.slideshare.net/tasheeen/active-ldap

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • RubyKaigi2010 企画 ”Ruby で扱う LDAP のススメ”資料です。

    数例ある事例紹介の内、谷口さんの事例紹介のスライドは以下にあります
    http://www.slideshare.net/tasheeen/active-ldap
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
14,049
On SlideShare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
44
Comments
1
Likes
6

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Ruby で扱う LDAP のススメ - Ruby meets LDAP - その選択肢と事例 - Choices and cases – 高瀬一彰 / @tasheeen
  • 2. Who? 高瀬一彰 (Kazuaki Takase) エイケア・システムズ株式会社 Lang: perl→php→ruby+javascript Rails で LDAP 管理アプリ
  • 3. Why? Ruby with LDAP に関する情報の不足 LDAP 自体がマイナー Ruby コミュニティに、LDAPを扱うため の入り口となる情報を提供したい LDAPって? どんなライブラリがあるの? どれを使えばいいの?
  • 4. What? LDAP の概略 LDAP ライブラリの紹介 事例紹介 コード例 参考資料一覧
  • 5. LDAPの概略
  • 6. LDAPの概略(1) Keywords LDAP Entry ObjectClass Attribute DIT Distinguished Name
  • 7. LDAPの概略(2) Lightweight Directory Access Protocol RFC4510などで定義 元々は DAP。その軽量版(=Lightweight) Directory = 台帳・名簿 何でも登録可能 台帳として最適化したデータ構造を持つ
  • 8. LDAPの概略(3) Entry LDAPにおけるデータの基本単位 =台帳の登録単位。名簿なら「人」 ≒RDBにおける行に近い 現実世界の「物(=オブジェクト)」を表す エントリは属性を持つ 「人」に対する「名前」「電話番号」etc. RDB と違う点 エントリがスキーマを持つ
  • 9. LDAPの概略(4) Object Class エントリが「何」か OOP の「クラス」と同義 オブジェクトクラスに よって持てる属性が変わる Unix アカウントのエント リなら posixAccount 継承・抽象型・構造型・補 助型などの概念とルール posixAccountは補助型 person 等と組み合わせる
  • 10. LDAPの概略(5) Attributes 一つの属性に複数の値 を持っている場合が多 い 台帳・名簿としての 考え方
  • 11. LDAPの概略(6) Directory Information Tree (DIT) ディレクトリデータベースを DIB ツリー構造していると DIT 階層的に管理するのがコンセプト エントリがツリーとして連なる
  • 12. LDAPの概略(7) Distinguished Name(DN) Rlative Distinguished Name(RDN) その階層における一意の 名前 cn=Ruby Taro エントリが持つ任意の属 性がRDNになる RDNを下から一番上まで cn=Ruby Taro,o=RubyKaigi2010,c=jp 繋げるとツリーで一意に 特定される名前になる (DN)
  • 13. Ruby with LDAP
  • 14. Ruby with LDAP - libs Obsolete ! Obsolete !
  • 15. Ruby with LDAP - libs RFC 1823の実装 Pure Ruby. ActiveRecordのLDAP版 character 拡張ライブラリ Rails と相性がいい 抽象度が高い ruby-ldap より10倍程 net-ldap よりも3倍程度 weak point ドキュメントが少ない 度遅い 遅い advantage 速い! ポータビリティが高い 高度な抽象化と豊富な機能 install gem install ruby-ldap gem install net-ldap gen install activeldap for use require “rubygems” require “rubygems” require “rubygems” require “ldap” require “net-ldap” require “active_ldap”
  • 16. Ruby with LDAP – ruby-ldap ruby-ldap RFC1823 (The LDAP Application Programming Interface) のRuby版実装 使い方は同梱のテストが参考になる 速い! bind search add modify C Extension etc…
  • 17. Ruby with LDAP – net-ldap net-ldap Pure Ruby な LDAP API 実装 ポータビリティに富む RDoc のドキュメントが結構しっかりしている bind search add modify Pure Ruby etc…
  • 18. Ruby with LDAP - activeldap activeldap ActiveRecord を参考に作られた、LDAP API ruby-ldap や net-ldap, JNDI を内部的に利用 クラスはツリーを抽象、インスタンスはエントリを抽象 ActiveLdap::Base find User new (Subclass) cn= save destroy
  • 19. Cases
  • 20. Case 1 事例提供者:カピバラさん http://sites.google.com/site/capibaraproject/home
  • 21. Case カピバラさん 背景 社内の各システム毎にID情報が分散 既存のLDAPサーバがあった 既存の構造的には認証統一には難しかった 新規にLDAP作成 管理アプリ作成 管理 ユーザ一覧/検索/新規作成/所属変更 パスワード初期化 等 ユーザ パスワード変更
  • 22. Case カピバラさん パスワード初期化 ユーザ管理 パスワード変更 一覧 検索 新規作成 所属変更
  • 23. Case カピバラさん ruby-ldap ActiveLdap は使いづらかったそうで回避(泣 確かに ruby-ldap の方がプリミティブな実装 ruby-ldapに限らず、LDAPについても情報が 不足して困った 速度面・利便性について特に不満なし
  • 24. Case 2 事例提供者:岡澤さん http://d.hatena.ne.jp/yujiorama/
  • 25. Case 岡澤さん ruby-ldap を利用 分散した社員マスタ/認証を統合 アカウント 作成・編集・削除 パスワード変更など ML 依頼があり次第 管理作業 参照できる 作成・変更 request
  • 26. Case 岡澤さん ruby-ldap 元々作った人が「Rails 関連は面倒」(笑 openldap のコマンドとほぼ同じような作り で、コマンドの使い方が判ると直観的に使え た 同様の理由で、デバッグ等もやりやすかった
  • 27. Case 3 事例提供者:谷口さん
  • 28. Case 4 事例提供者:高瀬
  • 29. Case 高瀬 activeldap アカウント/権限管理 sync batch ユーザ管理 batch (Create folder 有効化/編集/権限付与 (script/runner) & ACL settings) 退職処理 パスワード初期化など Password 共有フォルダ管理 Warning(mail) サブシステム権限管理 共有フォルダ etc 作成 権限編集 サブシステム権限編集 request パスワード変更
  • 30. Case 高瀬 activeldap Rails の機能を活用したかった script/runner でライブラリ使えるの便利 validation や association 使えるの便利 validationは作りによってはとっても遅くなる uid の uinique チェックのため検索するなどのvalidation を多数含めたりすると 検索時に取得する属性の数を少なくして速くする等の工夫 をすると吉 テストも Rails に統合 VM でdevelopment, test 用の LDAP を作成 環境(development, test)によって接続先 LDAP 切替 Rspec でふつうにテスト
  • 31. Code Examples
  • 32. Code Examples – ruby-ldap (1) Connection and Bind LDAP::Conn.new / LDAP::Conn#bind @conn = LDAP::Conn.new('localhost', 389) @conn.bind("cn=Manager,o=RubyKaigi2010,c=jp", pass) # => #<LDAP::Conn:0xb7f0d400> LDAP::Conn.new で接続 SSL接続には LDAP::SSLCon.new を利用 LDAP::Conn#bind でバインドする 第三引数の定数で認証方式の指定 Default: LDAP_AUTH_SIMPLE grep LDAP_AUTH ldap.c SSL 接続には LDAP::SSLConn
  • 33. Code Examples – ruby-ldap (2) search LDAP::Conn#search @conn.search("o=RubyKaigi2010,c=jp", LDAP::LDAP_SCOPE_SUBTREE, "(objectclass=*)") do |entry| entry # => #<LDAP::Entry:…>, #<LDAP::Entry:…>, … end 検索結果を LDAP ::Entry で返す ブロック必須 他にも結果を Hash で返す search2 がある Search2 はブロック無しで検索可能
  • 34. Code Examples – ruby-ldap (3) Add LDAP::Conn#add entry = {"objectclass" => ["top", "person"], "cn" => ["Ruby Taro"], "sn" => ["Ruby", "Taro"]} # 追加先のDN を指定し、属性の内容を渡す @conn.add("cn=#{entry['cn'][0]},o=RubyKaigi2010,c=jp", entry) # => #<LDAP::Conn:0xXXXXXXXX> HashやLDAP::MOD_ADD でエントリ追加 上記の例は Hash の場合
  • 35. Code Examples – ruby-ldap (4) Modify LDAP::Conn#modify mod_hash = {"sn" => ["hoge", "taro"]} @conn.modify("cn=Ruby Taro,o=RubyKaigi2010,c=jp", mod_hash) # => #<LDAP::Conn:0xb7f0bbc8> HashやLDAP::MOD_MOD でエントリ更新 上記の例は Hash の場合
  • 36. Code Examples – ruby-ldap (5) Gathering Error Information LDAP::Error begin @conn.delete("cn=Ruby Taro,o=RubyKaigi2010,c=jp") rescue => e e # => #<LDAP::ResultError: No such object> e.message # => "No such object“ @conn.err # => 32 @conn.err2string(@conn.err) # => "No such object" end 原則として LDAP::Error が投げられる様子 Human Readable なメッセージは LDAP::Error 自身が持っている エラーコードが欲しい場合に #<LDAP::Conn> に問い合わせる
  • 37. Code Examples – net-ldap(1) Connection and BIND Net::LDAP.new @ldap = Net::LDAP.new :host => 'localhost', :port => 389, :base => 'o=RubyKaigi2010,c=jp', :auth => { :method => :simple, :username => 'cn=Manager,o=RubyKaigi2010,c=jp', :password => password } @ldap # => #<Net::LDAP:0xb7e086f4 @base="o=RubyKaigi2010,c=jp",…> 接続と bind を一緒に行うのが通例
  • 38. Code Examples – net-ldap(2) search Net::LDAP#search @ldap.search # => [#<Net::LDAP::Entry: ...>, #<Net::LDAP::Entry ...>] @ldap.search(:filter => Net::LDAP::Filter.eq('uid', 'matz')) # => [#<Net::LDAP::Entry: … :uid=>["matz"], …>] デフォルトでは “(objectClass=*)” で検索 フィルタを利用する場合は Net::LDAP::Filter を利用して フィルタを構成する ブロックを渡してイテレーションさせることも可
  • 39. Code Examples – net-ldap(3) Add Net::LDAP#add attrs = { :objectclass => ["top", "inetOrgPerson", "posixAccount"], :cn => "ruby taro", :gidNumber => "1999", :homeDirectory => "/home/ruby_taro", :sn => ["ruby", "taro"], :uid => "ruby_taro", :uidNumber => "1999" } dn = "uid=#{attrs[:uid]},ou=Users,o=RubyKaigi2010,c=jp" @ldap.add(:dn => dn, :attributes => attrs) # => false @ldap.get_operation_result # => #<OpenStruct … "Success",…, code=0> ※何故か false を返してますが成功しています (僕の環境のせい?)
  • 40. Code Examples – net-ldap(4) Modify Net::LDAP#modify dn = "uid=ruby_taro,ou=Users,o=RubyKaigi2010,c=jp" opts = [ [:add, :mail, "hoge@example.com"], [:replace, :sn, ["hoge", "fuga"]], [:delete, :telephoneNumber] ] @ldap.modify(:dn => dn, :operations => opts) # => false ※これも何故か false を返してますが成功しています (僕の環境のry)
  • 41. Code Examples – net-ldap(5) Gathering Error Information Net::LDAP#get_operation_result @ldap.add(:dn => dn, :attr => attr) # => false @ldap.get_operation_result.code # => 2 @ldap.get_operation_result.message # => "Protocol Error" @ldap.get_operation_result.error_message # => "no attributes provided" @ldap.get_operation_result.matched_dn # => "" @ldap.get_operation_result # => #<OpenStruct …> OpenStruct でエラー情報を返す 上記は objectClass の MUST の属性を設定していない場合の例
  • 42. Code Examples – activeldap(1) Connection and Bind ActiveLdap::Base.setup_connection ActiveLdap::Base.setup_connection :base => "o=RubyKaigi2010,c=jp", :bind_dn => "cn=Manager,o=RubyKaigi2010,c=jp", :password_block => lambda{pass}, :logger => logger この時点では接続が確立されず、何か操作した時に接続 サブクラス毎に接続先を変えること等も可能
  • 43. Code Examples – activeldap(2) Mapping define subclass class User < ActiveLdap::Base ldap_mapping :prefix => "ou=Users", :classes => %w(person), :scope => :sub, :dn_attribute => "uid" end クラスを任意のツリーにマッピング このクラスを利用して指定したツリー以下の検索等を行う インスタンスを作成するとエントリにマッピングされる belongs_to, has_many 等も利用できる 全体的に ActiveRecord と類似したインターフェース
  • 44. Code Examples – activeldap(3) Search ActiveLdap::Base.find User.find(:all) # => [#<User ...>, #<User ...>, ...] User.find(:first, :filter => “(cn=Ruby Taro)”) #=> #<User ...> ActiveRecord と同様の検索方法 検索条件は :filter オプション エントリとマッピング済みのインスタンスを返す
  • 45. Code Examples – activeldap(4) Add/Modify ActiveLdap::Base#save , save! user = User.new :sn => 'Ruby', :cn => "Ruby Taro" user.save # => true user.sn = “Hoge” user.save # => true インスタンスの状態に合わせて add/modify 新規オブジェクトなら add 既存オブジェクトなら modify 属性に複数の値を入れたい場合は配列で
  • 46. Code Examples – activeldap(5) Gathering Error Information ActiveRecord::Validations#errors user = User.new :sn => 'Ruby', :cn => "Ruby Taro" user.save # => false user.errors # => #<ActiveRecord::Errors ...> user.errors.full_messages # => ["distinguishedName is duplicated: cn=Ruby Taro,ou=Users,o=RubyKaigi2010,c=jp"] errors メソッドが ActiveRecord::Errors を返す Rails で Webインターフェース等作る際は比較的楽
  • 47. 参考資料
  • 48. 参考資料 LDAP RFC 4510 http://datatracker.ietf.org/doc/rfc4510/ Rubyist Magazine - ActiveLdap を使ってみよう(前編)- LDAPとは http://jp.rubyist.net/magazine/?0027-ActiveLdap#l4 ruby-ldap Ruby/LDAP (Homepage) http://ruby-ldap.sourceforge.net/ RDoc http://ruby-ldap.sourceforge.net/rdoc/ ソースコード。特に test ディレクトリ以下 net-ldap Net-ldap-0.1.1 Documentation (Homepage) http://net-ldap.rubyforge.org/ activeldap ActiveLdap を使ってみよう(前編) http://jp.rubyist.net/magazine/?0027-ActiveLdap ActiveLdap を使ってみよう(後編) http://jp.rubyist.net/magazine/?0029-ActiveLdap Rails で作る ActiveDirectory と連携した社内システム http://www.clear-code.com/archives/rails-seminar-technical-night/ ActiveLdap 日本語チュートリアル http://code.google.com/p/ruby-activeldap/wiki/TutorialJa
  • 49. ありがとうございました Thank you.