認証

1. 認証機能について

iPLAssでは標準機能として認証に対する機能が組み込まれています。 以下の機能・特徴があります。

  • ID・パスワード認証
    標準機能として、 User エンティティとして管理するアカウントの情報に対して、ID・パスワードで認証を行う機能を提供します。 ユーザーのパスワード管理(ユーザー登録時のパスワード生成や通知、ユーザーによるパスワード変更など)を標準で実装しています。 また指定するパスワードに対する有効日数や複雑度、ログインエラー時のロック方法などを指定することができます。

  • Remember Me
    ログイン後、一定期間の間、認証情報の入力を省略するRemember Me機能を提供します。

  • 2段階認証
    メールやSMSによるワンタイムコードによる認証、2段階認証アプリ(Google Authenticator等)による認証、あらかじめ設定した質問に対する答えでの認証、 X509規格に基づいたクライアント証明書での認証機能を提供します。
    また特定の条件の場合のみ2段階認証を強要するなど、2段階認証の実行をカスタマイズすることができます。

  • 認証プロバイダー
    認証処理は認証プロバイダインタフェースを介して実行されます。 この仕組みを利用して、外部システムで保持しているアカウント情報での認証処理の実行など、独自の認証処理を実装することができます。

  • OAuth / OpenID Connect
    認証プロバイダーの実装として、OAuth2.0のアクセストークンによる認証およびOpenID Connect規格の認証を提供します。 これにより異なるドメイン間でのシングルサインオンが実現できます。
    詳細はOAuth / OpenID Connectを参照してください。

  • SAML
    認証プロバイダーの実装として、SAML2.0規格の認証を提供します。 これにより異なるドメイン間でのシングルサインオンが実現できます。
    詳細はSAMLを参照してください。

2. 標準の認証機能

標準で提供されている認証機能について説明します。

2.1. ログイン画面

標準提供のログイン画面

iPLAssでは、以下の3種類のログイン画面を標準で提供しています。

GEM(Generic Entity Manager)

エンティティの汎用データ操作画面群を提供するGEMモジュールに含まれるログイン画面です。
初期状態では、GEMモジュールのログイン画面がデフォルトで表示されます。

MDC(Mobile Design Components)

モバイルファーストなエンティティの汎用データ操作画面群を提供するMDCモジュールに含まれるログイン画面です。
MDCモジュールを有効化した場合は、MDCモジュールのログイン画面がデフォルトで表示されます。

WAM(Web Account Manager)

コンシューマ向けサイトの会員をiPLAss上で管理する機能を提供するWAMモジュールに含まれるログイン画面です。
作成するサイトに合わせてログイン画面を独自に用意する想定であり、iPLAssのWAMモジュールに含まれる標準のログイン画面はその雛形です。

ログイン画面の表示条件

以下のような条件でログイン画面が表示されます。

認証が必要なコンテンツへアクセスしようとした場合

ログインしていないユーザーが認証の必要なコンテンツへアクセスを試みた場合、ログイン画面が表示されます。 認証が正常に行われた場合、リクエストされたコンテンツにリダイレクトされます。

Action定義のAccess Policyにある privilege executepublic action を設定することで、未ログインのユーザーでもアクセスを可能にすることができます。
詳細は、Action定義(AdminConsole)を参照してください。
セッションがタイムアウトした場合

一定時間操作がなかった場合はログイン状態が解除され、再度ログイン画面が表示されます。

ログイン画面の出し分け

表示されるログイン画面の解決方法

ログイン画面は以下の優先度で決定されます。

  1. Tenantに設定された「ログイン画面Action制御Script」が返すAction名

  2. service-configの WebFrontendService#loginUrlSelector で設定されたSelectorが返すAction名

service-configの設定についてはLoginUrlSelectorを参照してください。
デフォルトでは gem/auth/login が設定されています。MDCモジュール を有効化した場合のデフォルトは mdc/auth/login になります。

「ログイン画面Action制御Script」でログイン画面を出し分ける具体例

「ログイン画面Action制御Script」とは、認証が必要なActionに対してリクエストされた場合に起動する制御Scriptです。 このScriptを設定することで、リクエストされたURLに含まれるパスを基にログイン画面を出し分けることが可能です。

例えば、システム運用者向けにはGEMのログイン画面、コンシューマ向けにはGEM以外のカスタムしたログイン画面(SAMLやOpenID Connectでシングルサインオンさせたい場合など)で画面を構成している場合に、 リクエストされたパスを判定して、表示するログイン画面のActionを切り替えることができます。

以下は、「ログイン画面Action制御Script」の設定例です。

if (path != null) {
    //pathがmemberで始まる場合は、メンバー用のログイン画面を利用
    //(member/loginというActionを自分で用意)
    if (path.startsWith("member")) {
        return "member/login";
    }

    //requestのパラメータはsetParamで変更可能です
    if (path.startsWith("admin")) {
        request.setParam("requireAsAdmin", 'true');
        return "admin/login";
    }
}

//nullが返された場合には、service-configの設定が適用されます
//(WebFrontendService#loginUrlSelector で設定されたSelectorが返すAction名でログイン画面が決定される)
return null;

このScriptで返ってきたActionにリダイレクトします。 その際、もともとアクセスしようとしたパスについてはrequestのattributeに redirectPath KEYで格納されます。

//redirectPathの定数
org.iplass.mtp.web.WebRequestConstants#REDIRECT_PATH;

具体的な設定内容については画面遷移設定を参照してください。

カスタマイズ

ログイン画面をカスタマイズしたい場合は、標準提供されているログイン画面を元にカスタマイズするか、コマンドおよびJSPを独自に実装する方法があります。
デフォルトでは以下のように実装されています。カスタマイズする際の参考にしてください。

  • GEMモジュール
    Command : gem/auth/LoginCommand
    Java ClassName : org.iplass.gem.command.auth.LoginCommand
    JSP : jsp/gem/auth/Login.jsp

  • MDCモジュール
    Command : mdc/auth/LoginCommand
    Java ClassName : org.iplass.mtp.mdc.command.auth.LoginCommand
    JSP : jsp/mdc/auth/login.jsp

  • WAMモジュール
    Command : wam/auth/LoginCommand
    Java ClassName : org.iplass.wam.command.auth.LoginCommand
    JSP : jsp/wam/auth/login.jsp

2.2. 認証情報の管理

認証の対象とするユーザーの属性情報は、 mtp.auth.User エンティティとして登録します。

ただしパスワード情報やログイン情報などは User エンティティのプロパティとしては管理していません。 t_account テーブルとして物理DBテーブルに保存されます。

ユーザー情報

ユーザーを管理するエンティティです。 認証で利用するプロパティ以外にもユーザーの属性に関する汎用的なプロパティが設定されています。

認証に関する項目
項目名 内容

ユーザーID

ユーザーのログイン時に入力IDです。テナント単位で一意である必要があります。必須項目です。

アカウントポリシー

ユーザーに対する認証ポリシーを指定します。

有効開始日

有効期間を設定します。有効期間を設定した場合、期限外となると、対象ユーザーは認証時にエラーとなります。

有効終了日

メールアドレス

ユーザーのメールアドレスを設定します。パスワードをメールで通知する場合に利用します。

一時ログインユーザー

一時的にログインを許可するユーザーを作成する場合に利用します。

IPアドレス履歴

2段階認証機能で利用します。

それ以外の項目
項目名 内容

ユーザーの姓名、姓名(カナ)をそれぞれ設定します。
姓のみ必須項目です。

姓(カナ)

名(カナ)

言語

テナントの多言語設定利用となっている場合のみ、設定した内容が有効となります。 iPLAssではユーザーの利用言語を設定する箇所が3つありますが、上のものほど優先度が高くなります。

  • 汎用画面のメニューで選択した言語

  • ユーザーEntityの言語

  • テナントのデフォルトロケール

管理者

システム管理者としてAdminConsoleの利用を許可する場合に設定します。

所属グループ

ユーザーをグループ化するための項目としてグループとランクという項目を標準で用意しています。 認可制御のためのロール管理で、条件として利用することも可能です。

所属ランク

標準で設定されているプロパティは削除したり多重度を変更しないでください。 プロパティの追加やメールアドレスを必須にするなどの変更は構いません(必須を外すことはしないでください)。

t_account

ユーザーの認証に関する情報を保持するDatabaseのテーブルです。

項目名 内容

tenant_id

テナントのID。

account_id

User エンティティのユーザーID。

password

パスワード。暗号化されます。

salt

パスワードを暗号化する際に付与されるデータ。

oid

User エンティティのOID。

last_login_on

最終ログイン日時。

login_err_cnt

ログイン失敗回数。

login_err_date

最終ログイン失敗日時。

pol_name

User エンティティのアカウントポリシー名。

last_password_change

最終パスワード変更日時。

cre_user

作成ユーザー

cre_date

作成日時

up_user

更新ユーザー

up_date

更新日時

パスワードの暗号化についての設定は、service-configの「AuthService」で指定します。 詳細についてはAuthServiceを参照してください。

ツール

認証情報は User エンティティと t_account で管理されているため、通常のエンティティ検索では情報が取得できません。 iPLAssではAdminConsole上に「BuiltinAuthUserExplorer」というツールを提供しています。
詳細は AuthUserExplorerを参照してください。

2.3. 認証ポリシーの設定

ユーザーが設定可能なパスワードの有効日数や複雑度、ログイン時の処理などは 認証ポリシー( AuthenticationPolicy )としてメタデータで管理します。 複数定義することで、ユーザーにあわせた認証方法を個別に設定することができます。

認証ポリシーは初期状態で DEFAULT という設定が登録されています。 ユーザー登録時にアカウントポリシーが未選択の場合、 DEFAULT が適用されます。

認証ポリシーの作成

AuthenticationPolicyアイコンを右クリックして「AuthenticationPolicyを作成する」を選択してください。

設定

認証ポリシーでは、以下の項目を設定します。

設定項目 内容

パスワードポリシー

パスワードの有効期限、複雑度、自動生成するパスワードに関する設定。

ロックポリシー

ログインに失敗した場合のユーザーのロックに関する設定。

Remember Meポリシー

Remember Me 機能を利用する場合の設定。

ロギング

ログインした際のログに関する設定。

通知

認証に関するイベントが発生した場合の通知設定。
この設定により、例えばユーザー作成時にメールでパスワードを通知するという処理を組み込むことができます。
通知設定については、 通知設定 で詳しく説明します。

認証プロバイダ

利用する認証プロバイダを指定します。
認証プロバイダについては、 認証プロバイダ で詳しく説明します。

2段階認証、リスク算出

2段階認証の種類や、2段階認証を実行するかの判断に関する設定。
2段階認証については、 2段階認証 で詳しく説明します。

代理ログイン

代理ログインに関する設定。 代理ログインについては、 代理ログイン で詳しく説明します。

SAML

SAMLを利用した認証に関する設定。 SAMLについての詳細はSAMLを参照してください。

パスワードポリシー
項目名 内容

maximum password age

パスワードが有効な最大期間 (日)。0は無限。

minimum password age

パスワード変更に最低限必要な期間(日)。

password pattern

パスワードの複雑度チェックに利用する正規表現。

deny same password as account id

アカウントIDと同じパスワードを指定不可とするか。

deny list

パスワードの拒否リスト。複数指定する場合は改行で区切ってください。
Userエンティティに紐づく情報は ${user.プロパティ名} と記述することで指定可能です。
例えば、 ${user.mail} でユーザーの mail を指定します。また、参照先のプロパティも ${user.groups.name} のような形で指定が可能です。

password pattern error message

パスワードの複雑度エラーのメッセージ。

random password include signs

自動生成で作成するパスワードに利用する記号。

random password exclude chars

自動生成で作成するパスワードで除外する文字。

random password length

自動生成で作成するパスワードの長さ。

maximum random password age

自動生成で作成するパスワードが有効な最大期間 (日)。0は無限。パスワードが自動生成された場合、ユーザーにこの日付をもとにした有効終了日がセットされます。 自動生成パスワードからパスワード変更した際に終了日はリセットされます。

custom user end date script

パスワードを自動生成されたパスワードから変更した際にリセットされるユーザーの終了日をカスタマイズしたい場合に指定します。 GroovyScript形式でTimestampのインスタンスを返却するように実装します。 未指定の場合、ユーザーの終了日にはnull(有効期限なし)が設定されます。

password history count

過去入力したパスワードを覚えておく個数。履歴に残っているパスワードは設定できなくなります。

password history period

過去入力したパスワードを覚えておく期間 (日)。履歴に残っている期間内のパスワードは設定できなくなります。

create account with specific password

アカウント作成の際、初期パスワードを指定可能とするか。

reset password with specific password

パスワードリセットの際、パスワードを指定可能とするか。

password history countpassword history period の両方が設定されている場合、パスワード保持個数内またはパスワード保持期間内のパスワードが設定できなくなります。
ロックポリシー

ロックした場合は、AdminConsoleなどでロックを解除する必要があります。

項目名 内容

lockout failure count

アカウントがロックする失敗回数。0はロックアウトしません。

lockout duration

ロックアウトしている期間(分)。0は無制限。

lockout failure expiration interval

失敗回数を記憶しておく期間(分) 。0は無制限。

Remember Me

Remember Me機能用の設定です。 Remember Me は、ログイン後、一定期間の間、認証情報の入力を省略する機能です。

Remember Me機能を有効化する場合は、AdminConsoleのTenant設定画面で「Remember Me機能を利用する」を 「利用する」に設定する必要があります。
項目名 内容

lifetime minutes

有効となる自動ログイン期間(分)。0はRememberMe機能を利用しないと同じ動作になります。

absolute lifetime

有効期間の開始日時。ONの場合は画面入力(ID/パスワード)によるログイン日時から有効期間まで、 OFFの場合は最終アクセス日時から有効期間まで。

ロギング
項目名 内容

record last login date

最終ログイン日時を記録する場合にONにします。

通知設定

ユーザー情報に変更が発生した際のリスナー設定です。 このListenerを設定することにより、ユーザー情報に対する変更を制御することが可能になります。 Listenerとしては、以下の3つのタイプを選択することが可能です。

タイプ 内容

Mail

メールを送信するためのListener。

Java Class

Javaで実装したListener。

Scripting

GroovyScript形式のListener。

Mail

メールを送信するためのListener定義です。

  • テンプレート定義
    各イベントに対するメールテンプレートを指定してください。

    項目名 内容

    create user

    ユーザー作成時のメールテンプレート名。

    credential reset

    パスワードリセット時のメールテンプレート名。

    create user with specified password

    パスワード指定によるユーザー作成時のメールテンプレート名。

    credential reset with specified password

    パスワード指定によるリセット時のメールテンプレート名。

    locked out

    ユーザーロック時のメールテンプレート名。

    credential updated

    パスワード変更時のメールテンプレート名。

    property updated

    プロパティ変更時のメールテンプレート名。
    Properties For Update Notification で指定されたプロパティに変更があった際に通知されます。

    remove user

    ユーザー削除時のメールテンプレート名。

    未指定の場合はメール送信は行いません。
  • バインド変数
    メールテンプレートには以下の変数がバインドされます。

    変数名 バインド値 クラス

    tenant

    対象テナント

    org.iplass.mtp.tenant.Tenant

    user

    対象ユーザー

    org.iplass.mtp.auth.User

    newPassword

    パスワード
    ユーザー作成時、パスワードリセット時のみ設定されます。 パスワード指定時やパスワード変更時などには設定されません。

    String

  • 送信設定
    宛先、送信元情報は以下の通り設定されます。

    設定項目 設定値

    TO送信先

    対象 User エンティティの mail プロパティに設定されたアドレス

    送信元、返信先

    テナントの設定値

    実際のメール送信処理は、メール送信機能の設定により行われます。 詳細はメールを参照してください。

  • Properties For Update Notification
    プロパティ変更通知としてチェックするプロパティを指定します。

Java

org.iplass.mtp.auth.policy.AccountNotificationListener

を実装したJavaクラスを指定してください。

Scripting

Groovyスクリプトで処理を定義します。 スクリプト形式での定義方法には2パターン存在します。

  • AccountNotificationListenerの実装
    Javaタイプと同様に、 org.iplass.mtp.auth.policy.AccountNotificationListener を実装したクラスを定義することが可能です。
    UtilityClassでの記載方法と同様の要領で記載してください。 パッケージは不要です。

  • Script形式での指定
    EntityのEventListenerと同様の形式で指定します。 「Notification Type」で選択したイベントに対して実行されます。 バインド変数として以下が設定されていますので、処理内で利用することが可能です。

    変数名 バインド値 クラス

    notification

    AccountNotificationのインスタンス。
    NotificationTypeuserOid を持っています。

    org.iplass.mtp.auth.policy.AccountNotification

    利用例
    import org.iplass.mtp.auth.policy.definition.NotificationType;
    
    if (notification.type == NotificationType.CREATED) {
        println "create user:" + notification.userOid;
    }

2.4. ユーザー管理

ユーザーの登録

ユーザーの登録は、 User エンティティを登録することで実行されます。

User に設定されている UserEntityEventListener によって、 t_account テーブルに連携されます。

ユーザー自身の編集

ログインユーザー自身でユーザー情報を編集することが可能です。汎用画面上部の「ユーザー情報変更」から実行します。

標準では、パスワードのみ変更が可能になります。

  • 編集可能項目の変更
    TopViewの設定により、変更が可能な項目を設定することができます。
    「Toolbar Parts」の「User Maintenance」をパーツエリアにドロップします。 User Maintenance パーツの設定で、 User エンティティに定義されたViewを指定することで、入力可能な項目を指定します。 標準で、 maintenance Viewが用意されています。

    admin Viewは全てのプロパティが設定されているため、指定しないでください。
    パスワードの保存と、ここで指定したユーザー情報の編集部分の保存処理は分かれています。
    maintenance View以外でも、独自にViewを定義することでカスタマイズすることが可能です。

パスワードの指定登録

標準設定ではユーザー登録時、パスワードリセット時にパスワードは自動で生成されます。 場合によっては登録時に明示的にパスワードを指定したい場合もあります。 登録時にパスワードを指定したい場合には以下の設定を行います。

  1. 認証ポリシーの設定
    認証ポリシーの Create Account With Specific Password にチェックを入れます。

  2. Detail Layoutの設定
    ユーザー登録で利用するDetailLayoutの設定を変更します。 User エンティティの詳細画面設定を開き、カスタム登録処理クラスを指定します。

    カスタム登録処理クラスに、標準で提供されている UserPasswordRegistrationInterrupter を指定します。

    org.iplass.gem.command.auth.UserPasswordRegistrationInterrupter

  3. パスワード項目の追加(仮想プロパティ)
    入力項目に「パスワード」を追加します。 User エンティティにはパスワードプロパティはありません。仮想プロパティを利用して追加します。

    プロパティ名は password にしてください。

    項目 設定値 備考

    新規/編集時の表示可否

    INSERT

    登録時のみ表示させます。

    詳細画面で非表示

    チェック

    詳細画面では非表示にします。

    プロパティエディタ

    StringPropertyEditor

    Editorの設定で、表示タイプに Password を指定します。

    パスワードを指定して登録する場合は、アカウントポリシーで Create Account With Specific Password を有効にした認証ポリシーを選択してください。
    DEFAULT 認証ポリシーで有効にしている場合は、アカウントポリシーを指定する必要はありません。

パスワードを入力して登録を実行すると、「カスタム登録処理クラス」で指定した UserPasswordRegistrationInterrupter の処理によって、パスワードが指定された状態で登録されます。

パスワードのリセット

ユーザー情報の編集画面上からパスワードのリセットを行うことができます。

リセット時には初期パスワードが発行されます。 認証ポリシーの通知設定によりメール通知も可能になります。 また、パスワードリセットを行うとログイン失敗時のカウントがリセットされます。

管理者の作成

AdminConsoleを利用するには User エンティティの admin プロパティが true になっている必要があります。

ただし標準のユーザー情報登録画面では admin プロパティの設定はできないようになっています。 予め User エンティティのView定義に定義されている admin Viewを利用するか、 新たにView定義を作成して admin プロパティを指定してください。

Viewを指定した汎用画面を表示するには、Menu定義で User エンティティに対するEntityMenuItemを作成しView Nameを指定します。 そのメニューをメニューツリーに設定します。

一時ユーザーの作成

iPLAssでは一時的に利用可能となるユーザーをシステム側で作成する事が可能です。

User エンティティのプロパティにある temporary プロパティを true にすることで、対象ユーザーは一時ユーザーとなります。

標準のユーザー情報登録画面では temporary プロパティの設定はできないようになっています。 予め User エンティティのView定義に定義されている admin Viewを利用するか、 新たにView定義を作成して temporary プロパティを指定してください。

一時ユーザーは「Temporary User Cleaner」バッチのクリーニング処理で一定期間を過ぎると自動的に削除されます。
詳細はTemporary User Cleanerを参照してください。

ユーザーデータの移行

各環境間でメタデータやエンティティデータのインポート、エクスポートを実行する場合があると思いますが、 テストユーザーなどの本番環境への誤った移行を防ぐため、ツールでの移行(簡単な手順での移行)はサポートしていません。

テスト環境間等での移行を行う場合には、下記のいずれかでご対応頂くようお願い致します。

  • 別途それぞれの環境でユーザーを作成する

  • User エンティティデータ及びデータベースの t_account テーブルデータそのものを移行する

iPLAssではPackagingというデータ移行ツールを提供していますが、これを利用しても t_account については移行されません。 User エンティティを移行した後に t_account も移行していただく必要があります。

直接INSERT文で登録、DBの機能を利用したエクスポート、インポート等、どのような方法で t_account を 移行していただいても問題ありません。 ただし、移行後の User エンティティの tenant_id , oidt_account テーブルの tenant_id , oid を一致させる必要があります。 (Packagingのインポートでoidをprefixつけて変更した場合は、その項目も洗い替えする) User エンティティの tenant_id , oid はEQL Worksheet等で確認して下さい。

移行イメージ

テスト環境1からテスト環境2にパッケージを利用して移行する場合のイメージは以下のようになります。

テスト環境1 User t_account

tenant_id:100

tenant_id:100

oid:100001

oid:100001

accountId:user0001

accountId:user0001

User エンティティのデータをAdminConsoleのパッケージを利用しエクスポート、インポートします。

テスト環境2 User t_account

tenant_id:001

oid:000001

accountId:user0001

インポート時に新しいテナントIDと自動採番された oid が付与されます。 また、 t_account のデータは移行されません。

続いて t_account のデータをDBの機能を利用しエクスポート、インポートします。

テスト環境2 User t_account

tenant_id:001

tenant_id:100

oid:000001

oid:100001

accountId:user0001

accountId:user0001

tenant_idoid はそのままインポートされるため、 User エンティティと差異が出てしまいます。

そこで t_account の対象データを User エンティティに合わせてアップデートします。

テスト環境2 User t_account

tenant_id:001

tenant_id:001

oid:000001

oid:000001

accountId:user0001

accountId:user0001

2.5. カスタマイズ

コンシューマ向けのユーザー登録画面や編集画面など独自に画面を作成している場合の認証情報の制御について説明します。

ユーザーの登録

ユーザーの登録は、汎用画面と同様に User エンティティを登録することで実行されます。 User エンティティに設定されている UserEntityEventListener によって、 t_account テーブルに連携されます。

パスワード指定登録

User エンティティにはパスワードがないので、Entityの登録だけではパスワードは指定できません。 User エンティティにパスワードを指定して登録してください。 UserEntityEventListener によって、パスワードが登録されます。

認証ポリシーの Create Account With Specific Password を有効にする必要があります。
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.entity.EntityManager;
import org.iplass.mtp.auth.User;

EntityManager em = ManagerLocator.manager(EntityManager.class);

//ユーザーの作成
User user = new User();
user.setAccountId("xxx");
user.setAccountPolicy("xxxxx"); //Create Account With Specific Passwordを指定したもの
user.setPassword("xxxxxx"); //パスワードをセット
・・・・

//登録
em.insert(user);

パスワード変更

パスワードの変更は、AuthManagerを利用して行います。 変更前のパスワードと変更後のパスワードが必要です。

import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.auth.AuthManager;
import org.iplass.mtp.auth.login.Credential;
import org.iplass.mtp.auth.login.IdPasswordCredential;
import org.iplass.mtp.auth.login.CredentialUpdateException;

AuthManager auth = ManagerLocator.manager(AuthManager.class);

//旧、新のCredentialを生成
Credential oldCredential = new IdPasswordCredential(accountId, oldPass);
Credential newCredential = new IdPasswordCredential(accountId, newPass);

//パスワード更新
try {
    auth.updateCredential(oldCredential, newCredential);
} catch (CredentialUpdateException e) {
    // エラー処理
}

パスワードリセット

パスワードのリセットは、AuthManagerを利用して行います。

import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.auth.AuthManager;
import org.iplass.mtp.auth.login.Credential;
import org.iplass.mtp.auth.login.IdPasswordCredential;
import org.iplass.mtp.auth.login.CredentialUpdateException;

AuthManager auth = ManagerLocator.manager(AuthManager.class);

//アカウントIDを指定したCredentialを生成
Credential credential = new IdPasswordCredential(id, null);

//パスワードリセット
try {
    auth.resetCredential(credential);
} catch (CredentialUpdateException e) {
    // エラー処理
}

パスワード指定リセット

パスワードを指定したリセットは、AuthManagerを利用して行います。

標準では、管理者のみパスワードのリセットが可能になっています。 もし管理者以外にパスワード指定によるリセットを許可する場合は、テナント設定の「ユーザー管理者ロール」に リセットを許可するロールを指定します。
詳細はテナントの認証設定を参照してください。

認証ポリシーの Reset Password With Specific Password を有効にする必要があります。
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.auth.AuthManager;
import org.iplass.mtp.auth.login.Credential;
import org.iplass.mtp.auth.login.IdPasswordCredential;
import org.iplass.mtp.auth.login.CredentialUpdateException;

AuthManager auth = ManagerLocator.manager(AuthManager.class);

String newPassword = "xxxxx";
//アカウントIDを指定したCredentialを生成
Credential credential = new IdPasswordCredential(id, newPassword);

//パスワードリセット
try {
    auth.resetCredential(credential);
} catch (CredentialUpdateException e) {
    // エラー処理
}

2.6. 2段階認証

2段階認証機能は、 後述する認証プロバイダー TwoStepAuthenticationProvider によって制御されます。

以下のいずれかに該当した場合に、2段階認証プロセスが起動します。

  • 手動でのID、パスワードでのログイン後

  • RememberMe機能による自動ログインの状態で、ユーザー情報変更を実施するとき

  • RememberMe機能による自動ログインの状態で、trusted authentication required が設定されたActionを呼び出すとき

2段階目の認証方式を選択することができます。

設定

2段階認証の方式としては、以下のタイプを選択することが可能です。

  • Onetime

  • TimeBased

  • KnowledgeBased

  • X509

Onetime

認証時にiPLAss内で生成したコードを送信し、それを入力することで認証を確認する方式です。

項目名 内容

display name

認証画面の「○○で認証」の○○部分に表示される名前

onetime code generator

ワンタイムの認証コードの通知方法の指定

outOfBandByMail

メールによる通知

outOfBandBySms

SMSによる通知

out of band property name

ワンタイム通知先として利用するユーザーEntityのプロパティ。メールアドレスなど。

TimeBased

事前に2段階認証アプリ(Google Authenticator等)で設定し、認証時に2段階認証アプリに表示されたコードを入力することで認証を確認する方式です。

項目名 内容

display name

認証画面の「○○で認証」の○○部分に表示される名前

issuer

2段階認証の設定画面のQRコードで発行者名として利用される名前。設定されていない場合はテナント名が発行者名として扱われます。

KnowledgeBased

登録済みの秘密の質問に回答することで認証を確認する方式です。

項目名 内容

display name

認証画面の「○○で認証」の○○部分に表示される名前

name

ナレッジベース認証における任意で一意の名前

required answer count

回答させる質問数。

lockout failure count

秘密の質問をロックアウトするまでの失敗回数。0はロックアウトしない。

failure count property

失敗回数を記憶しておくユーザーEntityのプロパティ。
予めInteger型のプロパティを User エンティティに追加してください。

select question setting

秘密の質問の設定

  • 秘密の質問
    秘密の質問は User エンティティのプロパティに回答を保持します。

    項目名 内容

    id

    質問を識別するID。一意の値

    contents

    質問内容

    answer property

    質問に対する回答を保存する User エンティティのプロパティ。
    予めString型のプロパティを User エンティティに追加してください。

X509

クライアントに設定された証明書を利用して認証を確認する方式です。

項目名 内容

display name

認証画面の「○○で認証」の○○部分に表示される名前

id must match

証明書内のIDがログインIDと一致している必要があるか

リスク評価

Risk Base Policy Setting を利用すると、ログイン時にユーザーに対するリスク評価を行い、 算出されたスコアの合計が一定の閾値を超えた場合に2段階認証を実行することができます。

項目名 内容

use risk based policy

2段階認証を行う際に2段階目の認証処理の実行有無をリスクベースで判断するか

threshold score

「リスクあり」と判断する閾値。リスク評価の合計スコアがこの閾値以上となる場合、2段階目の認証が行われます。

リスク評価の方法は以下のタイプから選択することが可能です。

  • CookieToken

  • HttpHeader

  • IPAddressHistory

  • IPAddressRange

  • JavaClass

  • ReAuthentication

  • Scripting

  • X509

それぞれの設定項目を記載します。

CookieToken

クッキー内に一定期間内に作られたトークンが存在するかで評価を行います。

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

lifetime minutes

有効となる期間(分)。0は無期限となる。

absolute lifetime

有効期間の開始日時。ONの場合は現在から有効期間まで、OFFの場合は最終アクセス日時から有効期間まで。

HttpHeader

HTTPヘッダ名に対応する値がMatch Patternにマッチするかで評価を行います。

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

header name

HTTPヘッダ名。

match pattern

HTTPヘッダの値のパターン。

IPAddressHistory

過去にアクセスされたIPアドレスか否かにより評価を行います。設定によりIPアドレス履歴の保持数、時間を設定可能です。

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

history counts

履歴の回数

lifetime minutes

有効となる期間(分)。0は無期限となる。

absolute lifetime

有効期間の開始日時。ONの場合は現在から有効期間まで、OFFの場合は最終アクセス日時から有効期間まで。

IPAddressRange

指定されたIPアドレス(の範囲)と一致するかで評価を行います。

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

IP address

対象となるIPアドレス(の範囲)。以下の形で指定が可能。

,(カンマ)

区切りによる複数IPアドレス(の範囲)の列挙

-(ハイフン)

区切りによるIPアドレス範囲の指定

/(スラッシュ)

区切りによるCIDR表記によるIPアドレス範囲の指定

192.168.0.0/16, 172.16.1.11-172.16.1.16, 172.16.0.1

JavaClass

独自のJavaクラス内で評価を行います。指定するクラスは下記のインターフェースを実装する必要があります。

org.iplass.mtp.auth.login.twostep.RiskEvaluator

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

class name

RiskEvaluatorを実装したJavaクラス名

init script

初期化スクリプトをGroovyスクリプトで記述します。

init scriptには、以下の変数がバインドされています。

バインド変数 バインド内容

policyName

認証ポリシー名

evaluator

Class Nameで指定したJavaクラスのインスタンス

ReAuthentication

再認証時にリスクありと判定します。 再認証が要求されるタイミングは trusted authentication required が設定されたActionが呼び出される際に、2段階目の認証がされていない状態の場合です。

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

Scripting

Groovyスクリプトで記述された内容で評価を行います。

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

script

リスク判定のスクリプトをGroovyスクリプトで記述します。

以下の変数がバインドされています。

バインド変数 バインド内容

credential

認証対象のCredential。

unmodifiableUniqueKeyOfUser

ユーザーを一意に特定する変更不可の一意なキー。 標準の認証機構を利用している場合はoidと同じです。

requestContext

認証要求があった際のRequestContext。

authenticationProviderName

認証プロバイダ名

X509

クライアントに設定された証明書の有無、IDの比較によって評価を行います。

項目名 内容

score

リスク評価内容に一致した際に加算されるスコア。マイナス値を指定した場合は減算される。

inverse result

リスク評価の結果を逆にする。

id must match

証明書内のIDがログインIDと一致している必要があるか。

2.7. 代理ログイン

この機能を有効にすると、ユーザーが別のユーザーとしてログインすることが可能になります(代理ログイン)。

ユーザーが代理でログインできる代理先ユーザーを指定する方法は2種類あります。

ユーザー指定

代理を許可するユーザー(代理される側)が、直接代理を許可するユーザーを指定する。 主に一般アプリユーザーでの利用を想定しています。

条件指定

User エンティティに対して代理可能範囲の条件を指定して、代理先のユーザーの直接的な許可を必要とせずに代理ログインを行う。 主にシステム管理者やテスト時等での利用を想定しています。

設定

項目名 内容

enable impersonation

代理ログインを許可するかを指定する。

ONの場合

メニューに「代理ログインする」が表示

OFFの場合

代理ログイン不可、直接代理を許可されていても利用出来ない

enable impersonation with no permission

条件指定での代理ログインを許可するかを指定する。

ONの場合

下記項目で指定する条件の範囲で代理ログインが可能になる

user condition for impersonation with no permission

User エンティティに対して代理可能な範囲をWhere条件として指定します。

user condition for impersonation with no permission

User エンティティに対して代理可能な範囲をWhere条件として指定します。 以下の変数がバインドされています。

バインド変数 バインド内容

permitUserOid

代理ログインする User エンティティの oid

targetUserOid

代理先の User エンティティの oid

(例)代理先ユーザーがgroup1またはgroup2に所属する場合は許可
groups.code in ('group1', 'group2')

PreparedQuery(GroovyTemplate)形式で実行されるため、複雑な条件を指定する場合はUtilityClassなどを利用してください。

3. 認証プロバイダ

認証プロバイダとは、認証する為の処理をモジュール化したものになります。 認証プロバイダを入れ替えることで、iPLAss標準のID、パスワードによる認証以外のさまざまな認証方式を利用する事が可能です。 また、カスタムプロバイダを作成し、独自の認証処理を利用することも可能です。

3.1. 標準の設定

認証プロバイダはmtp-service-config.xmlのAuthService定義内に設定します。 初期状態では以下の認証プロバイダが有効化されています。

Community Edition
  • BuiltinAuthenticationProvider (RememberMeTokenAuthenticationProviderに内包される)
    RememberMe トークンでの認証、ならびに内包するBuiltinAuthenticationProviderによるID、パスワードによる認証処理を行うプロバイダ。

  • AccessTokenAuthenticationProvider
    OAuth2.0のアクセストークンで認証処理を行うプロバイダ。

  • SimpleAuthTokenAuthenticationProvider
    単純なトークンでの認証処理を行うプロバイダ。

Enterprise Edition
  • TwoStepAuthenticationProvider (RememberMeTokenAuthenticationProviderに内包される)
    RememberMe トークンでの認証、ならびに内包するTwoStepAuthenticationProviderによる2段階認証を行うプロバイダ。
    TwoStepAuthenticationProviderは、 1段階目としてBuiltinAuthenticationProviderを利用したID、パスワードによる認証処理を行い、 2段階目として、ワンタイムコード、時間ベース(2段階認証アプリ)、ナレッジ(質問)、クライアント証明書を利用した認証を行います。

    プライマリ認証プロバイダ

    標準プロバイダ(BuiltinAuthenticationProvider)

    セカンダリ認証プロバイダ

    ワンタイムコード(OnetimeCodeAuthenticationProvider)
    時間ベース(TimeBasedAuthenticationProvider)
    ナレッジベース(KnowledgeBasedAuthenticationProvider)
    クライアント証明書(X509AuthenticationProvider)

    実際に2段階認証を実施するか、RememberMeトークンでの認証を許可するかは、認証ポリシーで設定します。

  • SamlAuthenticationProvider
    SAMLベースの認証処理を行う認証プロバイダ。
    SAMLベースの認証は、別途、SAML定義が行われ、認証ポリシーにて有効化された場合に処理されるようになります。

  • AccessTokenAuthenticationProvider
    OAuth2.0のアクセストークンで認証処理を行うプロバイダ。

  • SimpleAuthTokenAuthenticationProvider
    単純なトークンでの認証処理を行うプロバイダ。

3.2. 提供認証プロバイダ

各認証プロバイダや設定可能な項目についてはAuthServiceを参照してください。

3.3. カスタマイズ

認証プロバイダを独自で作成し、利用する事が可能です。 認証プロバイダは、 AuthenticationProvider インターフェースを実装して作成しますが、 予め汎用的な部分を設定した AuthenticationProviderBase クラスを継承して作成する方法もあります。

org.iplass.mtp.impl.auth.authenticate.AuthenticationProvider
org.iplass.mtp.impl.auth.authenticate.AuthenticationProviderBase

例として、 AuthenticationProviderBase クラスを継承したサンプルをもとに説明します。

実装する上での大きな流れとしては、以下の3つです。

  1. 認証したアカウント情報を保持するための AccountHandle インターフェースを実装したクラスを作成

  2. アカウント情報からUserエンティティを生成する UserEntityResolver インターフェースを実装したクラスを作成

  3. AuthenticationProvider でログイン処理の実装

package org.iplass.mtp.sample.auth;

import java.util.HashMap;
import java.util.Map;

import org.iplass.mtp.auth.User;
import org.iplass.mtp.auth.login.Credential;
import org.iplass.mtp.auth.login.IdPasswordCredential;
import org.iplass.mtp.impl.auth.AuthService;
import org.iplass.mtp.impl.auth.authenticate.AccountHandle;
import org.iplass.mtp.impl.auth.authenticate.AccountManagementModule;
import org.iplass.mtp.impl.auth.authenticate.AuthenticationProvider;
import org.iplass.mtp.impl.auth.authenticate.AuthenticationProviderBase;
import org.iplass.mtp.impl.auth.authenticate.UserEntityResolver;
import org.iplass.mtp.spi.Config;

public class SampleAuthenticationProvider extends AuthenticationProviderBase {

    /**
     * 認証プロバイダーの初期化処理を実装します。
     */
    @Override
    public void inited(AuthService service, Config config) {

        //独自のUserEntityResolverを設定 (1)
        if (getUserEntityResolver() == null) {
            SampleUserEntityResolver uer = new SampleUserEntityResolver();
            setUserEntityResolver(uer);
        }

        super.inited(service, config);
    }

    /**
     * ログイン処理を実装します。
     *
     * ログインが成功した場合は、AccountHandleを実装したクラスを返します。
     */
    @Override
    public AccountHandle login(Credential credential) { (2)
        IdPasswordCredential ipc = null;
        if (credential instanceof IdPasswordCredential) {
            ipc = (IdPasswordCredential) credential;
        } else {
            //違う場合はこのプロバイダでは認証しないので、nullを返す
            return null;
        }

        //認証処理の実装
        //ここは、認証するデータソースにあわせてそれぞれで実装します
        if (ipc.getId().equals("xxxx") && ipc.getPassword().equals("yyyy")) {
            //認証が成功した場合は、AccountHandleを実装したクラスのインスタンスを返します

            //AccountHandleに、ユーザー情報として持たせたい情報を設定します
            Map<String, Object> attributeMap = new HashMap<>();
            attributeMap.put("name", "test1");
            attributeMap.put("mail", "test@mail.com");

            return new SampleAccountHandle(ipc.getId(), attributeMap);
        }

        //認証失敗なのでnullを返す
        return null;
    }

    /**
     * ログアウト処理を実装します。
     */
    @Override
    public void logout(AccountHandle user) { (3)
        if (user instanceof SampleAccountHandle) {
            //対象のAccountHandleであれば、ログアウト時に必要な処理を実行
        }
    }

    /**
     * アカウント情報の更新可否、更新処理を管理するAccountManagementModuleを返します。
     */
    @Override
    public AccountManagementModule getAccountManagementModule() { (4)

        /*
         * この例では、AuthenticationProviderBaseで定義されている認証情報が変更不可なものを利用しています。
         * もし更新も可能にする場合は、AccountManagementModuleを実装したクラスを返します。
         */
        return AuthenticationProviderBase.NO_UPDATABLE_AMM;
    }

    /**
     * 対象とするCredentialを実装したクラス返します。
     */
    @Override
    public Class<? extends Credential> getCredentialType() {

        /*
         * この例では、ID、パスワードをもつIdPasswordCredentialを利用しています。
         * もし他の属性で認証したい場合は、Credentialを実装したクラスを返します。
         */
        return IdPasswordCredential.class;
    }

    /**
     * このプロバイダーでログインが成功した場合に保持するアカウント情報を管理するクラスを返します。
     */
    @Override
    protected Class<? extends AccountHandle> getAccountHandleClassForTrust() { (5)
        return SampleAccountHandle.class;
    }


    /**
     * ログインしたアカウント情報を保持するクラスです。
     */
    public class SampleAccountHandle implements AccountHandle { (6)

        private static final long serialVersionUID = 7558415988260650638L;

        /** 変更不可なユニークKEY */
        private String accountId;

        /** アカウントの属性として保持したい値 */
        private Map<String, Object> attributeMap;

        /** これは何番目のプロバイダーかの情報を保持するものです。基盤側で設定されるので保持してください */
        private int authenticationProviderIndex;

        public SampleAccountHandle(String accountId, Map<String, Object> attributeMap) {
            this.accountId = accountId;
            this.attributeMap = attributeMap;
        }

        @Override
        public boolean isAccountLocked() {
            return false;
        }

        @Override
        public boolean isExpired() {
            return false;
        }

        @Override
        public boolean isInitialLogin() {
            return false;
        }

        /*
         * 認証後に、色々な処理でアカウントの認証情報が求められた場合の認証情報を返します。
         * パスワード情報は認証時にしか使わないためAccountHandleには保持せずに、ここではセットしていません。
         */
        @Override
        public Credential getCredential() {
            return new IdPasswordCredential(accountId, null);
        }

        @Override
        public String getUnmodifiableUniqueKey() {
            return accountId;
        }

        @Override
        public Map<String, Object> getAttributeMap() {
            if(attributeMap == null){
                attributeMap = new HashMap<String, Object>();
            }
            return attributeMap;
        }

        @Override
        public void setAuthenticationProviderIndex(int authenticationProviderIndex) {
            this.authenticationProviderIndex = authenticationProviderIndex;
        }

        @Override
        public int getAuthenticationProviderIndex() {
            return authenticationProviderIndex;
        }

    }

    /**
     * アカウント情報からUserエンティティを生成するクラスです。
     */
    public class SampleUserEntityResolver implements UserEntityResolver { (7)

        @Override
        public void inited(AuthService service, AuthenticationProvider provider) {
        }

        /**
         * パラメータとして渡されたアカウント情報をもとにUserエンティティを返します。
         *
         * Userエンティティとしてデータを管理している場合はUserエンティティを検索して返しますが、
         * Userエンティティとして管理していない場合はここでUserエンティティを生成して返すように実装します。
         */
        @Override
        public User searchUser(AccountHandle account) {

            User user = new User();

            //ここではアカウント情報としてユニークな値をOIDに設定します
            user.setOid(account.getUnmodifiableUniqueKey());

            user.setAccountId(account.getCredential().getId());
            user.setName(account.getCredential().getId());

            //ここではaccountに設定された属性をUserエンティティに設定しています
            if (account.getAttributeMap() != null) {
                account.getAttributeMap().entrySet().stream().forEach(e -> {
                    user.setValue(e.getKey(), e.getValue());
                });
            }
            return user;
        }

        @Override
        public String getUnmodifiableUniqueKeyProperty() {
            //ユニークなKEYとなるプロパティ名を返します
            //OIDにユニークなKEYを設定しているので、OIDを返します。
            return User.OID;
        }

    }
}
1 UserEntityResolverは、認証に成功したアカウントの情報からUserエンティティを生成するクラスです。 AuthenticationProviderBaseで設定されている標準のUserEntityResolverは、Userエンティティを検索します。 Userエンティティとしてユーザーを管理していない場合は、独自でUserEntityResolverを生成してセットします。
2 ログイン処理を実装します。 ログインが成功した場合は、AccountHandleを実装したクラスを返します。 ログインが失敗した場合、または他の認証プロバイダで認証する場合はnullを返します。
3 ログアウト処理を実装します。
4 アカウント情報(パスワードなど)の更新可否、更新処理を管理するAccountManagementModuleを返します。 例えば外部システムでの認証処理などで、このシステムとしてアカウント情報を更新しない場合は、 AuthenticationProviderBase.NO_UPDATABLE_AMM を利用することも可能です。
5 独自で作成したAccountHandleを返します。
6 AccountHandleの実装クラスを定義します。
7 AccountHandle情報からUserエンティティを作成するUserEntityResolverクラスを定義します。

3.4. 複数プロバイダの利用

認証プロバイダは複数設定する事が可能です。 例えば、

  • 社外ユーザーはiPLAss標準の認証プロバイダ経由で認証させるようにし、社内ユーザーは社内のLDAPに保存されているユーザー情報を利用して認証させる

  • 通常のログイン方法(iPLAss標準のid/pass認証)に加えて、外部認証サービス(例えばOpenID Connect)経由での認証も可能にする

といったことが可能です。

認証プロバイダを複数設定した場合、認証時には、認証プロバイダの定義順に認証が成功するまで認証処理を試みます。 ただし、認証プロバイダの認証処理が明示的にExceptionをスローした場合は、その時点で認証処理は中断され、ログイン失敗となります。

設定

  • 既存のmtp-service-config.xmlに定義されるデフォルトを優先する場合
    mtp-service-config.xmlにてAuthServiceに対して、 authenticationProvideradditional="true" 指定で追加します。 この場合、認証プロバイダの定義順として、デフォルト設定されている認証プロバイダ⇒追加した認証プロバイダの順になります。

    :
    :
    <service>
      <interface>org.iplass.mtp.impl.auth.AuthService</interface>
    
      <property name="authenticationProvider"
            class="org.iplass.mtp.impl.auth.authenticate.ldap.LdapAuthenticationProvider" additional="true" >
        <property name="providerName" value="ad" />
        :
        :
    
      </property>
    
    </service>
    :
    :
  • デフォルト設定を上書きする場合
    mtp-service-config.xmlにてAuthServiceに対して、 authenticationProviderinherit="false" 指定で指定します。 この場合、標準で定義される設定を継承せず上書きする形になり、mtp-service-config.xmlに定義した認証プロバイダ順に処理が実行されます。

    標準の認証プロバイダも利用する場合は、mtp-service-config.xmlに標準の認証プロバイダの設定も記述する必要があります。

    :
    :
    <service>
      <interface>org.iplass.mtp.impl.auth.AuthService</interface>
    
      <property name="authenticationProvider"
            class="org.iplass.mtp.impl.auth.authenticate.ldap.LdapAuthenticationProvider" inherit="false" >
        <property name="providerName" value="ad" />
        :
        :
    
      </property>
    
      <property name="authenticationProvider"
            class="org.iplass.mtp.impl.auth.authenticate.rememberme.RememberMeTokenAuthenticationProvider" inherit="false" >
        <property name="authenticationProvider" class="org.iplass.mtp.impl.auth.authenticate.twostep.TwoStepAuthenticationProvider">
          <property name="primary" class="org.iplass.mtp.impl.auth.authenticate.builtin.BuiltinAuthenticationProvider">
            <property name="updatable" value="true" />
            <property name="providerName" value="default" />
            :
            :
    
          </property>
          :
          :
    
        </property>
      </property>
    
    </service>
    :
    :

認証したプロバイダの取得

複数の認証プロバイダを利用した場合に、Command処理などでどの認証プロバイダで認証したかの情報が必要になる場合は、 以下の方法で取得してください。

import org.iplass.mtp.auth.AuthContext;

AuthContext auth = AuthContext.getCurrentContext(); (1)

String providerName = (String)authContext.getAttribute("providerName"); (2)
1 Groovyの場合は、すでにバインドされている場合があります。
2 service-configで指定した providerName が返ります。