5.2. サンプル¶
5.2.1. 概要¶
ここでは、実際に開発プロセスに従って認証プロバイダ・プラグインの開発を行う手順を、例を利用しながら説明します。変更する認証方式は、 「LDAP 認証」を利用した認証方式とします。ここで例として利用するプロバイダは、「LDAP 認証モジュール」として intra-mart Accel Platform で実際に提供されているものです。LDAP 認証モジュールでは、LDAP サーバを認証サーバとして利用し、LDAP で管理するユーザ情報を利用して認証を行うように認証方式が変更されます。
5.2.2. ビジネスロジックの範囲を決定する¶
今回対応する範囲は、以下とします。
認証サーバとして LDAP サーバを利用します。 認証で利用する LDAP 情報は、ユーザコードとパスワードのみとします。実際に LDAP 認証を利用するためには以下の機能が必要ですが、認証プロバイダ・プラグインの説明の範囲外のため、ここでは扱いません。
LDAP にアカウント情報を登録する。 intra-mart Accel Platform のアカウント情報と LDAP のユーザ情報を同期する。
5.2.3. ビジネスロジックで必要となる認証プロバイダ・プラグインを決定する¶
ユーザコード、パスワードのみを扱うため、ログイン画面やリクエスト解析処理、画面遷移処理に変更はありません。標準で提供されるプロバイダをそのまま利用可能です。よって、認証を実行する「認証プロバイダ」のみ必要です。また、LDAP の利用可否を検証するため、「認証条件判定プロバイダ」も作成します。以上より、作成が必要なプロバイダは以下の通りです。
表 認証プロバイダ・プラグイン要否 プロバイダ名 要否 概要 初期リクエスト解析プロバイダ × リクエスト解析プロバイダ × 認証プロバイダ ◯ LDAP 認証サーバに認証を依頼します。 認証条件判定プロバイダ ◯ LDAP 認証サーバが有効かどうかを判定します。 認証リスナ × ログインページプロバイダ × 遷移先ページプロバイダ × これにより、今回作成する認証プロバイダを利用した認証フローは、「図 LDAP を利用した認証フロー」です。提供されないプロバイダは、標準認証モジュールのプロバイダを利用します。認証プロバイダは、標準認証モジュールのものは利用されず、LDAP 認証モジュール で提供されるプロバイダを利用します。
5.2.4. 認証プロバイダ・プラグインを実装する¶
仕様が決まりましたので、それぞれの認証プロバイダ・プラグインを実装します。LDAP を利用するために、LDAP サーバの情報にアクセスするための API が必要となってきますが、認証プロバイダ・プラグインが扱う範囲ではありませんので、以下が既に作成済みとします。
表 LDAP アクセス関連API APIクラス・インタフェース 概要 jp.co.intra_mart.system.security.certification.provider.ldap.LDAPContextInfoModel LDAP 認証を行うための設定情報を保持します。 jp.co.intra_mart.system.security.certification.provider.ldap.LDAPServerInfoModel LDAP サーバの接続情報を保持します。 jp.co.intra_mart.system.security.certification.provider.ldap.LDAPContextInfoBuilder LDAP 設定情報を読み込みます。 このAPIでは、以下のような情報が取得可能です。
LDAP 機能有効/無効フラグ LDAP サーバ一覧 LDAP サーバDN情報 LDAP 検索情報LDAP 認証モジュール では、これらの情報はシステム管理者の「テナント管理」画面の「LDAP連携・設定」から設定可能です。コラム
2013 Winter(Felicia) 以前のアップデートを利用する場合、LDAP の設定は設定ファイル「LDAP認証設定ファイル」で設定します。2014 Spring(Granada) 以降のアップデートを利用する場合、「LDAP認証設定ファイル」は「LDAP連携・設定」の初期値として利用します。
5.2.4.1. 作成する認証プロバイダ・プラグイン一覧¶
以下の プロバイダクラスを作成します。
表 LDAP 認証モジュール 認証プロバイダ一覧 プロバイダ名 実装クラス 認証条件判定プロバイダ jp.co.intra_mart.system.security.certification.provider.ldap.LDAPUserCertificationValidation 認証プロバイダ jp.co.intra_mart.system.security.certification.provider.ldap.LDAPUserCertification
5.2.4.2. 認証条件判定プロバイダ¶
LDAP 認証サーバが有効かどうかを判定する処理を実装します。以下に LDAP 認証モジュール で提供される認証条件判定プロバイダのソースの一部を例示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package jp.co.intra_mart.system.security.certification.provider.ldap; /** * 一般ユーザ用 LDAP 認証条件判定プロバイダ<BR> */ public class LDAPUserCertificationValidation implements UserCertificationValidation { /** LDAP 認証情報のインスタンスを格納します。 */ private LDAPContextInfoModel contextInfo; /** * コンストラクター */ public LDAPUserCertificationValidation() { // LDAP 認証情報モデルを作成します。 this.contextInfo = LDAPContextInfoBuilder.buildLDAPContextInfo(null); } /** * LDAP 認証サーバの利用可否を判定します。 */ public boolean validate(LoginInfo loginInfo, AccountInfo user, HttpServletRequest request, HttpServletResponse response) { // LDAP 認証が利用可能かどうかを検証し、結果を返します。 return this.contextInfo.isEnable(); } }環境情報などを参照して、認証モジュールの利用可否を判定してください。
5.2.4.3. 認証プロバイダ¶
LDAP サーバに認証を問い合わせる処理を実装します。認証サーバへの問い合わせは、JNDI API を利用して行うことができます。詳しい情報については、JDK の API ドキュメントを参照してください。javax.naming.directory.InitialDirContext.InitialDirContext以下に LDAP 認証モジュール で提供される認証プロバイダのソースの一部を例示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 package jp.co.intra_mart.system.security.certification.provider.ldap; /** * 一般ユーザ用 LDAP 認証プロバイダ<BR> */ public class LDAPUserCertification implements UserCertification, XmlInitParamable { /** LDAP 認証情報のインスタンスを格納します。 */ private LDAPContextInfoModel contextInfo; /** * ユーザログイン認証の初期化を行います。 <BR> */ @Override public void init(Node node) { // LDAP 認証情報モデルを作成します。 this.contextInfo = LDAPContextInfoBuilder.buildLDAPContextInfo(node); } /** * LDAP 認証サーバに認証を依頼します。 */ public CertificationStatus certification(LoginInfo loginInfo, AccountInfo user, HttpServletRequest request, HttpServletResponse response) { // 設定された LDAP 認証サーバの数だけループさせます。 for (LDAPServerInfoModel serverInfo : this.contextInfo.getLDAPServers()) { DirContext dirContext = null; try { // 検索するための設定を取得します。 dirContext = new InitialDirContext(serverInfo.getSearchEnvironment()); // 検索フィルタにユーザコードを設定します。 String filter = serverInfo.getSearchFilter().replaceAll("\\?", loginInfo.getUserCd()); // LDAP でユーザの検索を実行します。 NamingEnumeration<SearchResult> answer = dirContext.search(serverInfo.getBaseDn(), filter, serverInfo.getSearchControls()); // 検索結果が存在するかを判定します。 if (answer.hasMoreElements()) { SearchResult sr = (SearchResult) answer.nextElement(); // ユーザの検索結果を基にパスワードの検証を行います。 // 入力されたパスワードを認証情報として LDAP サーバに認証を依頼します。 String name = sr.getName(); dirContext = new InitialDirContext(serverInfo.getCertifyEnvironment(name, ",", loginInfo.getPassword())); // ここまで来たら LDAP 認証成功したこととします。 return CertificationStatus.CR_OK; } } catch (CommunicationException e) { // 通信例外が発生した場合、エラーとします。 return CertificationStatus.CR_ERROR; } catch (NamingException e) { // ユーザの検索、またはパスワードの検証に失敗した場合、次の LDAP サーバで検証を行います。 continue; } } return CertificationStatus.CR_NG; } }intra-mart Accel Platform の LDAP 認証モジュール では、複数の LDAP 認証サーバを登録することが可能です。そのため、取得した LDAP サーバに対して順にユーザの問い合わせを行っています。問い合わせは、以下の処理を順に行います。
ユーザコードの問い合わせ 問い合わせたユーザを基にした、パスワードの検証問い合わせた結果ユーザコードが見つからなかった場合やパスワードの検証に失敗した場合には NamingException が発生します。その場合は、次の認証サーバで検証を行うように処理を継続しています。処理結果により、以下を返却します。
表 認証処理結果 条件 処理結果 ユーザが存在し、パスワード検証が成功した場合 CertificationStatus.CR_OK すべての認証サーバでユーザ検索・パスワード検証を行い、検証に失敗した場合 CertificationStatus.CR_NG 通信エラーなどで LDAP サーバのアクセスに失敗した場合 CertificationStatus.CR_ERROR 注意
ここで例として記述しているソースでは、実際のソースの省略可能な部分を省略しています。例えば、InitialDirContext のクローズ処理は記述していません。
5.2.5. 認証プロバイダ・プラグインを登録する¶
5.2.5.1. plugin.xml の作成¶
plugin.xml を作成します。今回は、認証プロバイダのみですので、以下の1つのみを作成し、「認証プロバイダ」、「認証条件判定プロバイダ」を記述してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8"?> <plugin> <extension point="jp.co.intra_mart.security.user.certification"> <certification name="standard" id="jp.co.intra_mart.security.user.certification.ldap" version="8.0" rank="90"> <certification-class>jp.co.intra_mart.system.security.certification.provider.ldap.LDAPUserCertification</certification-class> <certification-validation> <validation-class>jp.co.intra_mart.system.security.certification.provider.ldap.LDAPUserCertificationValidation</validation-class> </certification-validation> </certification> </extension> </plugin>注意
intra-mart Accel Platform の 標準プロバイダの「rank」属性は、「100」が設定されています。プラグインは、「rank」属性の小さい順に読み込まれますので、「100」より小さい値を設定する必要があります。
5.2.5.2. Web Application Server で動作確認する¶
Web Application Server で動作を確認するためには、作成したクラスと plugin.xml を Web Application Server のデプロイ先にコピーします。モジュールを作成することで、War ファイルの作成時に自動的に正しい場所に配置されますが、ここでは動作確認のために以下のパスに手動でコピーします。ファイルの配置後に、Web Application Server を起動します。これにより、作成した認証モジュールが選択され、LDAP サーバによる認証方式が利用されます。実際に LDAP 認証方式を利用するためには、LDAP サーバの構築と、LDAP の利用情報の設定が必要です。intra-mart Accel Platform のLDAP 認証モジュールを利用した場合の LDAP の利用情報の設定は、「 セットアップガイド 」-「 設定ファイル 」-「 LDAP認証設定ファイル 」を参照してください。LDAP サーバの構築は、利用する LDAP サーバのドキュメントを参照してください。