8月 042012
急に、LDAPにアクセスしてみたくなったので、勉強がてら作ってみました。
よく使われそうな、シンプルなLDAPの認証はもちろん
特定のグループにだけ許可のようなことも可能です。
VCLはロジックがかけるので、親和性が高いんじゃないかなと考えています。
シンプルなLDAPを使ったBASIC認証
import ldap; sub vcl_error { if (obj.status == 401) { set obj.http.WWW-Authenticate = {"Basic realm="Authorization Required""}; synthetic {"Error 401 Unauthorized"}; return(deliver); } } sub vcl_recv{ if(req.url ~ "^/member/"){ if(!(req.http.Authorization &;amp;&;amp; ldap.simple_auth( true, //V3プロトコルで接続するか "cn=Manager,dc=ldap,dc=example,dc=com", //バインドアカウント(User) "password", //バインドアカウント(Pass) "ldap://192.168.1.1/ou=people,dc=ldap,dc=example,dc=com?uid?sub?(objectClass=*)", //LDAP接続先 ldap.get_basicuser(), //認証したいアカウント(User) ldap.get_basicpass() //認証したいアカウント(Pass) ))){ error 401; } }
グループとユーザで制限してみる
import ldap; sub vcl_deliver{ //LDAPを閉じる ldap.close(); } sub vcl_error{ if (obj.status == 401) { set obj.http.WWW-Authenticate = {"Basic realm="Authorization Required""}; synthetic {"Error 401 Unauthorized"}; return(deliver); } } sub vcl_recv{ if(req.url ~ "^/member/"){ //LDAPに接続 if(!(req.http.Authorization &;amp;&;amp; ldap.open( true, //V3プロトコルで接続するか "cn=Manager,dc=ldap,dc=example,dc=com", //バインドアカウント(User) "password", //バインドアカウント(Pass) "ldap://192.168.1.1/ou=people,dc=ldap,dc=example,dc=com?uid?sub?(objectClass=*)", //LDAP接続先 ldap.get_basicuser(), //認証したいアカウント(User) ldap.get_basicpass() //認証したいアカウント(Pass) ))){ error 401; } //グループの照合 if(!ldap.compare("cn=test,ou=people,dc=ldap,dc=example,dc=com","memberUid")){ldap.close();error 401;} //ユーザの照合 if(!ldap.require_user("uid=hogehoge,ou=people,dc=ldap,dc=example,dc=com")){ldap.close();error 401;} //パスワードの照合 if(!ldap.bind()){ldap.close();error 401;} ldap.close(); } }
ちなみにget_basicuserとget_basicpassを使うと
BASIC認証を行った時に送られてくるAuthorizationヘッダからユーザIDとパスを取得する事ができます。
なおシンプルな認証で使うsimple_authは内部ではopenとbindとcloseを呼び出しています。