それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

ApacheでLDAPを使ったBasic認証の設定

ApacheBASIC認証でhtdigest/htpasswdを使わずに、LDAPへ問い合わせる事にした。LDAPだとAD連携も出来るし便利。だけど、LDAPデータベースは検索遅い。

事前設定で必要なこと(apache2.conf またはhttpd.conf)

#モジュールロード
LoadModule ldap_module modules/mod_ldap.so
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
#設定
LDAPVerifyServerCert Off   #オレオレ証明書でエラーにしない
LDAPOpCacheTTL 1           #設定テスト中なのでLDAP問い合わせをキャッシュ1秒

認証に必要な設定(.htaccessなど)

AuthName "User/Password"              #Basic認証のダイアログで出てくる
AuthType Basic                        #Basic認証するよ!
AuthBasicProvider ldap                #パスワードはLDAP使うよ!
AuthzLDAPAuthoritative  off           #LDAP以外の認証は組み合わせないよ!
AuthLDAPURL  ldaps://ldap.example.ac.jp/ou=Students,dc=example,dc=ac,dc=jp?uid
                                      #検索クエリ。解説は後で
AuthLDAPBindDN "cn=sso_admin,dc=example,dc=ac,dc=jp"
                                      #bind dn  
AuthLDAPBindPassword "bind_password"  #bind_dn のパスワード
require valid-user                    #ユーザー認証が通るか

.htaccess に書く。.htaccessに掛けると言うことは、Location/Directoryでもいけるね。

Apache-LDAP連携方法は2つ

連携方法は2つあります。LDAP接続するのに、だれのID/PWで接続するかで違う

  1. ブラウザから入力されたモノを使う。
  2. 事前に決めたID/PWで接続し、ブラウザから入力されたユーザーを検索して、PASSWDが一致するか調べる.

どっちでもいいけど、LDAPといえば通常後者かな。
後者の場合

AuthLDAPBindDN "cn=sso_admin,dc=example,dc=ac,dc=jp" #bind dn  
AuthLDAPBindPassword "bind_password"  #bind_dn のパスワード

を設定する。これ設定したらあとは自動的にcompareリクエスト発行してくれる便利。

検索URI

LDAPURIで表現される。つまりリソース。URIって事はRESTfulですね。HTTPではないですが、URIで表現できるので便利です。

ldaps://ldap.example.ac.jp/ou=Students,dc=example,dc=ac,dc=jp?uid

は見たまんな分解されて

ldaps:// ldaps/ldapでスキームを指定
ldap.example.ac.jp ホスト名
/ou=Students,dc=example,dc=ac,dc=jp パス。つまりLDAPノード,search base dn ね
?uid 検索条件・・・属性,スコープ,フィルタ,

ノードのエントリのobjectclassに、userPassword,uidがあれば、それをid/pwに使います。Apacheのmod_ldap+mod_auth_ldapは賢いね。
uid以外も指定することも出来るけど。あまりやらないよね。

ldapsの場合

ldapsの場合は。オレオレ証明書に注意する。自己証明書を受け入れる設定と、authの設定は場所が違うのです。

条件指定も出来る

LDAPの属性値に基づいた条件指定が掛ける。

require valid-user #認証出来たユーザー
require ldap-attribute is_active=on #有効アカウントだけ

他にも、LDAPURIのフィルタで指定してもイイ

認証出来たらどうするの

認証出来たら、ユーザーIDとパスワードがApache環境変数に入る。CGI/PHPからは、Apache環境変数を見れば使うことが出来る。

<?php
echo $_SERVER["AUTHENTICATE_UID"]	#=> takuya_1st  これは mod_authnz_ldap提供  
echo $_SERVER["PHP_AUTH_USER"]      #=> takuya_1st   Basic認証から
echo $_SERVER["PHP_AUTH_PW"]	    # => my_password Basic認証から
?>

といっても、ログ・mod_rewrite で使うことが殆ど。Apacheから貰うくらいなら、通常はCGIで動かしたPHP/rubyから、LDAPにbindしてCompareしちゃう。

https と組み合わせ

Basic認証なので当然HTTPSと組み合わせて使うし、HTTPでのアクセスは拒否しないとね。それでもブラウザは送ろうとするし、BASICは丸見え。ユーザーが不用意にHTTPで送っちゃうかもしれない。なので、実験が終ったらDigestにしておきたい。

LDAPでdigestはよく解らない。

LDAP-Apache連携をやってみて。

ADが既存のシステムであるなら、LDAP側にミラーして使えるので便利。LDAPに集約しようとしたけれどLDAP検索は遅いので意外と不便かもしれない。Sambaもつかえるけど、LDAPだと多用なモノと連携できる。OAuthとLDAPはそれぞれレイヤ7でしっかりした認証の連携が出来る。SSOも可能になる。ただし、Cookieと違って「認証済み:authenticated」の状態をどう表現するかがまだ難しい。この辺が論文になるかなぁ。

軽量で扱いやすいと説明されるLDAPだけど、仕組みを理解するのは面倒で。。

単なるKVSなLDAP

LDAPだってWindowsのレジストリと同じ、ツリー型のストレージなんだけど・・・各ノード情報を横断的に検索する機能を持つ。ただ、この検索が遅い。
レジストリやファイル検索と同じノリで検索するので、遅い。もちろん事前INDEX作成すれば早いんだけど。
 インデックス作成して認証に使うなら、KVSやMySQLMyISAM使った方が早いよね。・・・LDAPいみねぇ。ベンダが高額分捕るための規格になってる。