2011年9月2日金曜日

[APEX]認証方式をLDAP認証にする



  • 概要
APEX4.0@Oracle11gではデフォルトのままではLDAP認証できない。
10gでは何の問題もなくWEB画面で設定するのみで認証できたがナゼ・・?
原因は不明でLDAP API作って実装しました
  • 経緯
SQL/PLUSで直接LDAP認証を試みてみる。

DECLARE
retval PLS_INTEGER;
my_session DBMS_LDAP.session;

BEGIN
retval:= -1;
my_session:= DBMS_LDAP.init('ldap.host.com',389);
retval:=DBMS_LDAP.simple_bind_s(my_session,'uid=my-id,ou=ldap,ou=host,c=com',my-password');
END;
エラーが…
ORA-31202: DBMS_LDAP: LDAP client/server error: Invalid credentials
いろいろ調べてみると…。

セキュリティーの為、UTL_TCP, UTL_HTTP, UTL_SMTP, UTL_MAIL, UTL_INADDRといったPL/SQLパッケージのメソッドを実行するには、ACLベースの権限を付与する必要がある。
ACL を付与するには、DBMS_NETWORK_ACL_ADMIN パッケージで行う。
存在するACL は、DBA_NETWORK_ACLS ,DBA_NETWORK_ACL_PRIVILEGES ビューで参照可能。

とのこと。
おそらくLDAP通信にてUTL_TCPあたりのパッケージを使っているのだろう。

sqlplusにてDBAでログイン
SQL> conn test/test@xe as sysdba
現在の状況を確認
select * from dba_network_acls;
select * from dba_network_acl_privileges;
APEXでLDAP認証できるように、ACLを作成(ldap.xmlは任意のACL名?、スキーマ名はEDU、ldap.host.comはホスト名)

begin
-- ACLを作成
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL('ldap.xml', 'ACL for ldap', 'EDU',true,'connect');
-- ユーザーにACLで定義した権限を割り当て
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE('ldap.xml','EDU',true,'resolve');
-- ACLに対応する接続先を割り当て
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL('ldap.xml','ldap.host.com');
end;
/

正常に設定されると以下のメッセージが表示される。
PL/SQL procedure successfully completed.
ACLを削除するときは以下のプロシージャを実行します。
DBMS_NETWORK_ACL_ADMIN.DROP_ACL('ldap.xml');

と、これでうまくいくはずだったのですが結局できず…
以下のファンクションを作って対処することになりました…
むむぅ・・・

-----
create or replace function LDAP_AUTH(p_username in varchar2, p_password in varchar2)
return BOOLEAN
is

userdn varchar2(4000);
userpassword varchar2(4000);

retval PLS_INTEGER;
my_session DBMS_LDAP.session;

begin
-- 認証対象のユーザのDN
userdn:= 'uid=' || p_username || ',ou=ldap,ou=host,o=com';
userpassword:= p_password;

retval:= -1;
my_session:= DBMS_LDAP.init('ldap.host.com',389);
retval:= DBMS_LDAP.simple_bind_s(my_session, userdn, userpassword);

 if (retval = -1) then
   return false;
 else
   return true;
 end if;

end;