intra-mart Accel Platform 認証プログラミングガイド 第7版 2018-04-01

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 のユーザ情報を同期する。

../../_images/ldap_component.png

図 LDAP 構成

5.2.3. ビジネスロジックで必要となる認証プロバイダ・プラグインを決定する

ユーザコード、パスワードのみを扱うため、ログイン画面やリクエスト解析処理、画面遷移処理に変更はありません。
標準で提供されるプロバイダをそのまま利用可能です。
よって、認証を実行する「認証プロバイダ」のみ必要です。
また、LDAP の利用可否を検証するため、「認証条件判定プロバイダ」も作成します。
以上より、作成が必要なプロバイダは以下の通りです。
表 認証プロバイダ・プラグイン要否
プロバイダ名 要否 概要
初期リクエスト解析プロバイダ ×  
リクエスト解析プロバイダ ×  
認証プロバイダ LDAP 認証サーバに認証を依頼します。
認証条件判定プロバイダ LDAP 認証サーバが有効かどうかを判定します。
認証リスナ ×  
ログインページプロバイダ ×  
遷移先ページプロバイダ ×  

これにより、今回作成する認証プロバイダを利用した認証フローは、「図 LDAP を利用した認証フロー」です。
../../_images/certification_flow_ldap.png

図 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 ファイルの作成時に自動的に正しい場所に配置されますが、ここでは動作確認のために以下のパスに手動でコピーします。
../../_images/provider_deployment.png

図 プロバイダの配置先


ファイルの配置後に、Web Application Server を起動します。
これにより、作成した認証モジュールが選択され、LDAP サーバによる認証方式が利用されます。

実際に LDAP 認証方式を利用するためには、LDAP サーバの構築と、LDAP の利用情報の設定が必要です。
intra-mart Accel Platform のLDAP 認証モジュールを利用した場合の LDAP の利用情報の設定は、「 セットアップガイド 」-「 設定ファイル 」-「 LDAP認証設定ファイル 」を参照してください。
LDAP サーバの構築は、利用する LDAP サーバのドキュメントを参照してください。