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を呼び出しています。