intra-mart Accel Platform セットアップガイド 第29版 2019-08-01

11.8. テナント解決機能

11.8.1. 概要

この章では、バーチャルテナント機能利用時における、操作対象のテナントがどのように解決されるかを説明します。
intra-mart Accel Platform では、アカウントコンテキストのテナントIDプロパティが、操作対象のテナントを意味しています。
アカウントコンテキストのテナントIDプロパティは、テナント解決機能を利用して解決されます。
以降では、テナント解決機能の仕様について説明します。
なお、intra-mart Accel Platform 上に作成するプログラムは、操作対象のテナントを意識する必要はありません。
(操作対象のテナントは、このページで説明するテナント解決の仕組みによって自動的に解決されます。)

11.8.1.1. リクエスト情報を利用したテナント自動解決機能について

intra-mart Accel Platform では、リクエスト情報を利用して操作対象となるテナントを決定することが可能です。
この機能を利用することにより、利用者の認証状態を問わず特定のテナントが操作対象に指定され、ログイン時にテナントIDを指定する必要がありません。
例えば、URLのサブドメインを利用してテナントの自動解決を行うことで、以下のように、URLごとに操作対象となるテナントを決定することが可能です。
../../../_images/resolve_tenant_for_url.png

コラム

標準では、リクエスト情報を利用したテナント自動解決機能は利用しません。
リクエスト情報を利用したテナント自動解決機能は、「IM-SecureSignOn for Accel Platform」アプリケーションや、機能を提供するモジュールを利用することで有効に設定できます。

コラム

リクエスト情報を利用したテナント自動解決機能を実装する方法については、「リクエスト情報を利用したテナント自動解決機能を提供する」を参照してください。

11.8.2. テナント解決のパターン

Webアクセス時にテナントを解決するパターンは、以下の通りです。
  • 一般ユーザ
    • ログイン時にテナントを指定する場合
    • リクエスト情報を利用したテナント自動解決機能を利用する場合
  • システム管理者

11.8.2.1. 一般ユーザ

11.8.2.1.1. ログイン時にテナントを指定する場合

テナントが複数存在する場合は、一般ユーザのログイン画面でテナントを指定してログインを行います。

ログインに成功すると、ログイン画面で指定したテナントが操作対象のテナントに指定されます。
ログアウトを行うことで、未認証状態となり、デフォルトテナントが操作対象に切り替わります。
未認証状態では、デフォルトテナントが操作対象のテナントに指定されています。
../../../_images/normal_flow.png

11.8.2.1.2. リクエスト情報を利用したテナント自動解決機能を利用する場合

リクエスト情報を利用したテナント自動解決機能を利用することで、リクエストの任意の情報からテナントの解決を行うことが可能です。
この機能を利用している状態では、ログイン/ログアウトにより操作対象テナントが切り替わることは無く、ログイン画面でテナントを指定してログインを行うことはできません。
未認証状態では、自動解決されたテナントが操作対象のテナントに指定されています。
../../../_images/resolved_tenant_flow.png

11.8.2.2. システム管理者

システム管理者の場合、操作対象のテナントはデフォルトテナントに指定されています。
システム管理者は、テナントの切り替え機能を利用して操作対象のテナントを切り替えることが可能です。詳細は「システム管理者操作ガイド」の「テナントの切り替え」を参照してください。

11.8.3. リクエスト情報を利用したテナント自動解決機能を提供する

11.8.3.1. 概要

リクエスト情報を利用したテナント自動解決機能が有効な場合、操作対象のテナントは、以下の流れで解決されます。
  1. 提供されているテナント自動解決機能にて、テナントIDの解決を行います。
  2. 提供されているテナント検証機能にて、テナントIDの検証を行います。
  3. テナントIDをアカウントコンテキストのテナントIDプロパティに設定します。
以下では、テナント自動解決機能テナント検証機能 とその提供方法について説明します。

11.8.3.2. テナント自動解決機能

リクエスト情報から、テナントIDを解決する機能です。

RequestBasedTenantIdResolver インタフェースを実装したクラスを作成し、プラグイン設定ファイルを設定することで、リクエスト情報を利用したテナント自動解決機能を利用することが可能です。

テナント解決機能は、複数設定して提供することが可能です。
複数のテナント解決機能が提供されている場合は、プラグインの仕様に従い、優先度の高いテナント解決機能から順番に実行されます。
テナントの解決が行われた(getTenantId(HttpServletRequest) メソッドで null 以外を返した)時点でテナント解決処理が終了します。後続のテナント解決機能は実行されません。
テナントが解決できない(getTenantId(HttpServletRequest) メソッドで null を返した)場合は、後続のテナント解決機能にてテナントの解決を行います。
全てのテナント解決機能がテナントを解決できなかった(全て null を返した)場合、次項の テナント検証機能 の検証で問題がなかった場合は、 デフォルトテナントと解決されます。

11.8.3.2.1. テナント自動解決機能の作成

以下のインタフェースを実装したクラスを作成します。
  • jp.co.intra_mart.foundation.admin.tenant.context.RequestBasedTenantIdResolver
以下はCookieを利用してテナントを解決するサンプル実装です。
package sample.context;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import jp.co.intra_mart.foundation.admin.tenant.context.RequestBasedTenantIdResolver;

public class CookieTenantIdResolver implements RequestBasedTenantIdResolver {

    private static final String COOKIE_KEY = "X-TENANT-ID";

    @Override
    public String getTenantId(final HttpServletRequest request) {
        return getCookieValue(request, COOKIE_KEY);
    }

    private Cookie getCookie(final HttpServletRequest request, final String name) {
        final Cookie[] cookies = request.getCookies();

        if (cookies == null) {
            return null;
        }

        for (final Cookie cookie : cookies) {
            if (name.equals(cookie.getName())) {
                return cookie;
            }
        }

        return null;
    }

    private String getCookieValue(final HttpServletRequest request, final String name) {
        final Cookie cookie = getCookie(request, name);

        if (cookie == null) {
            return null;
        }

        return cookie.getValue();
    }

}

コラム

RequestBasedTenantIdResolver インタフェースの詳細は「RequestBasedTenantIdResolverインタフェースのAPIリスト」を参照してください。

11.8.3.2.2. テナント自動解決機能の設定

テナント自動解決機能はプラグインファイルで設定を行います。従って、プラグインの機能を利用した設定が可能です。
リクエスト情報を利用したテナント自動解決機能を設定するための拡張ポイントは jp.co.intra_mart.foundation.admin.tenant.context.tenant.resolvers です。
作成したプラグインファイルを WEB-INF/plugin/sample_tenant_resolver/plugin.xml に配置します。(plugin直下のフォルダ名は、他のプラグインと重複しない名前で任意に変更することが可能です。)
上記のCookieを利用したテナント自動解決機能の実装を動作させるプラグイン設定のサンプルは以下の通りです。
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <extension point="jp.co.intra_mart.foundation.admin.tenant.context.tenant.resolvers">
        <tenant-id-resolvers
            id="sample.context.cookie_resolver"
            version="1.0.0"
            rank="1">

            <!-- tenant-id-resolver タグは複数指定可能です。 -->
            <!-- RequestBasedTenantIdResolverインタフェースを実装したクラスの完全修飾クラス名をclass属性に指定してください。 -->
            <tenant-id-resolver class="sample.context.CookieTenantIdResolver" />

        </tenant-id-resolvers>
    </extension>
</plugin>

コラム

プラグインの設定仕様については、「PluginManagerのAPIリスト」を参照してください。

上記の資材をデプロイすると、Cookieのキー X-TENANT-ID の値をテナントIDとして扱います。

11.8.3.3. テナント検証機能

テナント自動解決機能により解決したテナントIDが妥当な値であるかを判別する機能です。

テナント自動解決機能により解決したテナントIDは検証機能にてエラーとならない場合、アカウントコンテキストのテナントIDプロパティに設定されます。例えば、存在しないテナントIDがアカウントコンテキストのテナントIDプロパティに設定されてしまうと intra-mart Accel Platform が提供する機能が正常に動作しなくなります。このような状態を回避するために、テナント検証機能にて妥当性チェックを行います。

テナント検証機能は、複数設定して提供することが可能です。
複数のテナント検証機能が提供されている場合は、プラグインの仕様に従い、優先度の高いテナント検証機能から順番に実行されます。
テナントの検証にてエラー(validate(String, Resource) メソッドで InvalidTenantIdException )が発生した時点でテナント検証処理が終了します。後続のテナント検証機能は実行されません。

11.8.3.3.1. テナント検証機能の作成

以下のインタフェースを実装したクラスを作成します。
  • jp.co.intra_mart.foundation.admin.tenant.context.TenantIdValidator
以下にサンプル実装を例示します。
package jp.co.intra_mart.foundation.admin.tenant;

import jp.co.intra_mart.foundation.admin.tenant.context.TenantIdValidator;
import jp.co.intra_mart.foundation.context.core.Resource;
import jp.co.intra_mart.foundation.admin.tenant.InvalidTenantIdException;

public class SampleTenantIdValidator implements TenantIdValidator {

    @Override
    public void validate(final String tenantId, final Resource resource) throws InvalidTenantIdException {

        if (tenantId != null && !tenantId.startsWith("TENANT_")) {
            // テナントID書式チェック
            // テナントIDが "TENANT_" で始まっていることをチェックします。
            throw new InvalidTenantIdException("テナントIDの書式が正しくありません。");
        }

    }

}

コラム

TenantIdValidator インタフェースの詳細は「TenantIdValidatorインタフェースのAPIリスト」を参照してください。

11.8.3.3.2. テナント検証機能の設定

テナント検証機能も、テナント自動解決機能と同様にプラグイン設定ファイルで設定を行います。
テナント検証機能を設定するための拡張ポイントは jp.co.intra_mart.foundation.admin.tenant.context.tenant.validators です。
以下にサンプルのプラグイン設定ファイルを例示します。
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <extension point="jp.co.intra_mart.foundation.admin.tenant.context.tenant.validators">
        <tenant-id-validators
            id="sample.context.sample_tenant_id_validator"
            version="1.0.0"
            rank="1">

            <!-- tenant-id-validator タグは複数指定可能です。 -->
            <!-- TenantIdValidatorインタフェースを実装したクラスの完全修飾クラス名をclass属性に指定してください。 -->
            <tenant-id-validator class="sample.context.SampleTenantIdValidator" />

        </tenant-id-validators>
    </extension>
</plugin>

11.8.3.3.3. StandardTenantIdValidator

標準で提供されている TenantIdValidator の実装クラスです。
テナント自動解決機能によるテナント解決チェック、テナントの存在チェックなどを行います。
11.8.3.3.3.1. 完全クラス修飾子
jp.co.intra_mart.system.admin.context.StandardTenantIdValidator
11.8.3.3.3.2. プラグインの初期化パラメータ
StandardTenantIdValidator は、PropertyInitParamable インタフェースを実装しているため、 プラグイン設定ファイルにて初期化パラメータを受け渡すことが可能です。
初期化パラメータは <init-param> タグで指定します。
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
    <extension point="jp.co.intra_mart.foundation.admin.tenant.context.tenant.validators">
        <tenant-id-validators
            id="jp.co.intra_mart.tenant_id.validator.standard"
            version="8.0.7"
            rank="100">
            <tenant-id-validator class="jp.co.intra_mart.system.admin.context.StandardTenantIdValidator">

                <init-param>
                    <param-name>required_tenant_id</param-name>
                    <param-value>true</param-value>
                </init-param>
                <init-param>
                    <param-name>valid_tenant_id</param-name>
                    <param-value>true</param-value>
                </init-param>

            </tenant-id-validator>
        </tenant-id-validators>
    </extension>
</plugin>
param-name 説明
required_tenant_id
テナントIDが解決されているかを検証します。true / false で指定し、true の場合は検証を行います。
テナントIDが解決されていない場合は、例外 InvalidTenantIdException が発生し、システムにアクセスできません。
省略した場合は、検証を行いません。
valid_tenant_id
解決されたテナントIDが存在するテナントのテナントIDであるかを検証します。true / false で指定し、true の場合は検証を行います。
解決されたテナントIDが存在するテナントのテナントIDではない場合は、例外 InvalidTenantIdException が発生し、システムにアクセスできません。
省略した場合は、検証を行いません。

コラム

PropertyInitParamable インタフェースの詳細は「PropertyInitParamableインタフェースのAPIリスト」を参照してください。