1. 認可機能について
iPLAssでは標準機能として認可に対する機能が組み込まれています。 以下の機能・特徴があります。
-
ロールベースの権限制御
ロールベースの権限制御機能を提供します。 ユーザーの属性や所属グループなどを割り当て条件としたロールを定義し、各ロールにEntity権限、Action権限、WebApi権限などの権限を付与することで、ユーザーのアクセスを制御することが可能です。
2. ロールの管理
iPLAssでは、ロールは mtp.auth.Role
エンティティとしてデフォルトで定義されています。
ロールの管理は、ユーザー毎に付与するのではなく、ロール側で付与された割り当て条件によってユーザーに割り当てられます。
ロールに対して権限を付与することで、個々のユーザーに対してではなく、ある範囲のユーザーに対してまとめて権限を制御する事が可能です。
ロールの管理は、GEM画面の「権限情報」のメニューに表示される各設定画面から行うことが出来ます。
管理者(admin)であれば、AdminConsoleの「Tools」に表示されている「PermissionExplorer」から行うことも可能です。
PermissionExplorerの詳細は PermissionExplorerを参照してください。
2.1. ロールのプロパティ
項目名 | 内容 |
---|---|
ロールコード |
任意のロールコードを指定します。テナント単位で一意である必要があります。 |
名前 |
ロールの表示名を指定します。 |
優先順位 |
優先順位を設定します。Action権限等にロールを複数設定した場合に適用させるロールの優先順位となります。設定値が大きい方が優先されます。 |
説明 |
本ロールの説明を設定します。 |
本ロールの割り当て条件を設定します。 |
|
ロールに付与されたAction権限の参照情報となります。 |
|
ロールに付与されたEntity権限の参照情報となります。 |
|
ロールに付与されたWebApi権限の参照情報となります。 |
|
ロールに付与されたWorkflow権限の参照情報となります。 |
|
ロールに付与されたUserTask権限の参照情報となります。 |
|
ロールに付与されたCube権限の参照情報となります。 |
各権限の情報編集は直接行えません。権限の各設定においてロールの指定と条件を設定します。 GEMの画面ではリンクで表示され、リンクをクリックすることで権限の設定画面に遷移します。 |
ロール条件
ロール条件はGroovyScript形式で定義します。
ユーザー情報などチェック対象の属性がバインド変数として渡されるので、判定結果を true/false
で返すように実装します。
ロール条件は複数設定することができます。複数設定した場合はORとして判定します。
どれか1つでも true
であればロールに該当すると判断されます。
いくつか例を示します。
-
User
エンティティの所属グループで判定
所属グループ(groups
)を条件としたい場合、以下のようにグループコードを指定することで、そのグループに属しているメンバーを条件とすることができます。 グループは階層構造を持っているため、memberOf
関数が提供されています。user.memberOf("TEST001")
-
User
エンティティのランクで判定
所属ランク(rank
)も条件に指定可能です。「ユーザーのランクのレベル属性が5以上」といった定義になります。user.rank.level > 5
-
未ログインユーザーの判定
未ログインユーザーを条件とする場合はanonymousフラグを利用します。 anonymousフラグはユーザー情報のプロパティではありませんが、ログイン状態に応じてuserに付与されています。user.anonymous==true
バインド変数などの詳細は各種条件の書式を参照してください。
3. 権限管理
iPLAssでは、機能ごとの権限(Entity、Action、WebAPI、Workflow、UserTask、Cube)をEntityとして管理しています。
ロールに対して、機能ごとの権限を利用目的に応じて設定し、ロールに権限を付与することでアプリケーションの利用範囲や権限が異なるロールを作成することができます。
Entity権限では、Entityの各操作(登録、参照、更新、削除)に対して許可/不許可及び、許可範囲を設定し、その他権限(Action、WebAPI、Workflow、UserTask、Cube)では、アクションの実行を許可/不許可及び、許可範囲を設定し、アクセス制御を行います。
3.1. Entity権限
Entityの各操作(登録、参照、更新、削除)の許可/不許可及び、許可範囲の設定を行います。 また、プロパティ単位で許可するプロパティを指定できます。
Entityレベルでの許可範囲はあくまでEntity単位に対してのものであり、プロパティに対してのものではありません。 対象Entity内のプロパティに対して、自ユーザーのデータは参照可能、他ユーザーのデータは参照不可、といった指定はできません。 そのような制御をしたい場合は、参照可能範囲を変えたい属性類を別Entityに定義してEntityレベルで参照範囲を絞って下さい。 尚、参照プロパティについては、参照先エンティティの権限も設定する必要があります。
Entityに対する権限が未設定の場合の挙動は以下の形です。
-
いずれのロールに対しても権限が未設定の場合
ログインユーザーのみEntityの各操作(登録、参照、更新、削除)は許可 -
いずれかのロールに対して権限が設定されている場合
権限が設定されていないロールのユーザーの各操作は不許可
項目名 | 内容 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
名前 |
Entity権限の表示名を設定します。 |
||||||||||
対象Entity |
対象とするEntityを設定します。 |
||||||||||
ロール |
対象とするロールを設定します。 |
||||||||||
参照権限の設定 |
|
||||||||||
登録権限の設定 |
|
||||||||||
更新権限の設定 |
|
||||||||||
削除権限の設定 |
|
参照可能範囲条件
参照可能範囲条件は、 PreparedQuery(GroovyTemplate)形式で定義します。 対象のエンティティに対するWHERE条件を設定します。
ユーザー情報等がバインド変数として用意されており、条件として利用することができます。
バインド変数を利用する場合は$で括る必要があります。 |
いくつか例を示します。
-
直接文字列で指定
col01
プロパティの値が01
のもののみを対象とする場合は以下のように記述します。col01='01'
-
バインド変数
user
を利用
バインド変数を利用する場合は以下のように記述します。oid = '${user.oid}'
-
inの指定
下記のようにtoIn
を利用し、プロパティの型に対応する値のCollection、配列、単一オブジェクトを指定する事も可能です。 ただし、参照型に対してEntityを直接指定することは出来ません。group.oid in (${toIn(user.groupOid)}) group.oid in (${toIn(user.groupOidWithChildren)}) groupCode in (${toIn(user.groupCode)}) groupCode in (${toIn(user.groupCodeWithChildren)}) customPropertyCode in (${toIn(user.customPropertyCode)})
-
副問い合わせでの注意点
Oracleを利用している場合に、条件式に以下のような形で副問い合わせで定義した場合、OracleでORA-01799エラーが発生します。 (refer句にて、oid=(Select ~)を記述するとエラーとなる)oid=(select groups.oid from mtp.auth.User where oid='${user.oid}')
oidに対して副問い合わせを限定条件として記述したい場合、下記のように定義してください。
oid in (select groups.oid from mtp.auth.User where oid='${user.oid}')
Entity権限のエンティティ
Entityに対する権限は、EntityPermission
エンティティとして管理します。
mtp.auth.EntityPermission
3.2. Action権限
特定のActionに対してのアクセス制御が可能です。
Action権限は対象Actionの階層(「/」の区切り)毎に権限が評価されます。対象Actionの階層に権限が未設定だった場合、上位の階層の権限をチェックし、権限が見つかるまで確認します。権限が未設定の場合の挙動は以下の形です。
-
いずれのロールに対しても権限が未設定の場合
ログインユーザーのみActionの実行は許可 -
いずれかのロールに対して権限が設定されている場合
権限が設定されていないロールのユーザーの実行は不許可
詳細は、複数ロールの場合のAction権限を参照。
項目名 | 内容 |
---|---|
名前 |
Action権限の表示名を設定します。 |
対象とするAction名を指定します。 |
|
ロール |
対象とするロールを設定します。 |
許可する条件を記述します。 |
対象Actionの指定
Action名を個別に指定する以外に、ワイルドカード(*を指定可能)を利用する事もできます。 設定するのはコンテキスト、テナント名を除くアクション名のみとなります。
例)下記URLのサービスに対して制御する場合(mtpがコンテキスト、demoがテナント名)
-
hogehogeアクションのみを制御したい場合
site/hogehoge
-
site配下を制御したい場合
site/*
複数ロールの場合のAction権限評価について
対象Action | ロールA | ロールB |
---|---|---|
site/* |
設定 |
設定 |
site/path/* |
未設定 |
設定 |
site/another/* ※説明のために記載。実際には設定しない定義 |
未設定 |
未設定 |
上記のような階層で定義された対象Actionの場合、パスの深い階層からチェックして対象Actionが存在すれば、その階層の権限チェックをする仕様となります。
例えば、ロールAのユーザーが以下のURLにアクセスした場合
/site/path/*
にロールBに紐づく権限が設定されているので、その階層でチェックし、ロールAの権限は未設定のため、権限なしと判断され、Action実行不可
となります。
また、ロールAのユーザーが以下のURLにアクセスした場合
/site/another/*
の権限は、どのロールにも設定されていないので、上位の /site/*
の階層でチェックし、権限ありと判断され、/site/*
の権限通り制御されます。
許可条件
許可条件はGroovyScript形式で定義します。
ユーザー情報やリクエストパラメータなどチェック対象の属性がバインド変数として渡されるので、判定結果を true/false
で返すように実装します。
いくつか例を示します。
-
全てを許可
設定したロールを保持するユーザー全てに対して許可したい場合はtrue
と設定して下さい。true
-
リクエストパラメータで制限
リクエストパラメータを条件に指定する事も可能です。defNameがHogeEntityの場合に許可parameter.defName == 'HogeEntity'
-
リクエストパラメータで複数の値をチェック(in)
in
句を利用して第一引数にパラメータ名、第二引数以降に条件としたい値を指定することも出来ます。defNameがHogeEntityもしくFugaEntityの場合に許可parameter.in('defName', 'HogeEntity', 'FugaEntity')
-
複数のリクエストパラメータで制限
defNameがHogeEntityかつaaaが1の場合に許可parameter.defName == 'HogeEntity' && parameter.aaa == '1'
バインド変数などの詳細は各種条件の書式を参照してください。
Action権限のエンティティ
Actionに対する権限は、ActionPermission
エンティティとして管理します。
mtp.auth.ActionPermission
3.3. WebApi権限
特定のWebApiに対してのアクセス制御が可能です。
WebApi権限もAction権限同様、対象の階層(「/」の区切り)毎に権限が評価されます。実行するWebApiの階層に権限が未設定だった場合、上位の階層の権限をチェックし、権限が見つかるまで確認します。権限が未設定の場合の挙動は以下の形です。
-
いずれのロールに対しても権限が未設定の場合
ログインユーザーのみWebApiの実行は許可 -
いずれかのロールに対して権限が設定されている場合
権限が設定されていないロールのユーザーの実行は不許可
Action権限と同様となります。詳細は、複数ロールの場合のAction権限を参照。
項目名 | 内容 |
---|---|
名前 |
WebApi権限の表示名を設定します。 |
対象WebApi |
対象とするWebApi名を指定します。指定方法はAction権限の対象Actionと同様です。 |
ロール |
対象とするロールを設定します。 |
許可条件 |
許可する条件を記述します。指定方法はAction権限の許可条件と同様です。 |
WebApi権限のエンティティ
WebApiに対する権限は、WebApiPermission
エンティティとして管理します。
mtp.auth.WebApiPermission
3.4. Workflow権限
Workflow権限はあくまでワークフローを起動する為の権限であり、承認タスクなどはワークフロー内の設定に従います。
ここで設定された許可条件に該当するユーザーがWorkflowを開始することができます。
権限が未設定の場合の挙動は以下の形です。
-
いずれのロールに対しても権限が未設定の場合
ログインユーザーのみWorkflowの開始は許可 -
いずれかのロールに対して権限が設定されている場合
権限が設定されていないロールのユーザーのWorkflowの開始は不許可
項目名 | 内容 |
---|---|
名前 |
Workflow権限の表示名を設定します。 |
対象Workflow |
対象とするWorkflow名を指定します。 |
ロール |
対象とするロールを設定します。 |
許可条件 |
許可する条件を記述します。指定方法はAction権限の許可条件と同様です。 |
Workflow権限のエンティティ
Workflowに対する権限は、WorkflowPermission
エンティティとして管理します。
mtp.auth.WorkflowPermission
3.5. UserTask権限
UserTask権限は割り当て済みのタスクを割り当てられてないユーザーが各操作(タスクの操作、ユーザーの割当変更)を実行するための権限です。
権限が未設定の場合の挙動は以下の形です。
-
いずれのロールに対しても権限が未設定の場合
全てのユーザーの各操作は不許可 -
いずれかのロールに対して権限が設定されている場合
権限が設定されていないロールのユーザーの各操作は不許可
項目名 | 内容 |
---|---|
名前 |
UserTask権限の名称を設定します。 |
対象Workflow |
対象Workflowを設定します。 |
対象UserTask |
対象UserTaskを設定します。 |
ロール |
対象とするロールを設定します。 |
管理 |
管理操作に対する、「許可」、「不許可」を設定します。 |
管理可能範囲条件 |
管理可能範囲を設定します。
指定方法はEntity権限の参照可能範囲条件と同様です。
|
UserTask権限のエンティティ
UserTaskに対する権限は、UserTaskPermission
エンティティとして管理します。
mtp.auth.UserTaskPermission
3.6. Cube権限
特定のCubeに対してのアクセス制御が可能です。
Cubeに対する権限が未設定の場合の挙動は以下の形です。
-
いずれのロールに対しても権限が未設定の場合
ログインユーザーのみCubeの参照は許可 -
いずれかのロールに対して権限が設定されている場合
権限が設定されていないロールのユーザーの参照は不許可
項目名 | 内容 |
---|---|
名前 |
Cube権限の名称を設定します。 |
対象Cube |
対象Cubeを設定します。 |
ロール |
対象とするロールを設定します。 |
参照 |
参照操作に対する、「許可」、「不許可」を設定します。 |
参照可能範囲条件 |
参照可能範囲を設定します。指定方法はEntity権限の参照可能範囲条件と同様です。 |
参照項目の制御 |
「参照項目のリスト」プロパティに対して、「参照可」、「参照不可」を設定します。 |
参照項目のリスト |
対象とするプロパティを設定します。カンマ区切り、もしくはスペース区切りで複数指定が可能です。 |
Cube権限のエンティティ
Cubeに対する権限は、CubePermission
エンティティとして管理します。
mtp.auth.CubePermission
4. 各種条件の書式
条件として指定する方法には、GroovyScript形式で true
/ false
を返す記述と、
PreparedQuery(GroovyTemplate)形式で記述する方式が存在します。
4.1. GroovyScript形式
GroovyScript形式で条件を設定するEntityは以下になります。
Entity | 設定項目 | バインド変数 | バインド内容 |
---|---|---|---|
ロール |
ロール条件,条件文 |
user |
ユーザー情報が取得できます。 |
session |
セッション情報が取得できます。(バッチなど、APサーバ経由の起動以外の場合はバインドされません。) |
||
request |
リクエストの情報が取得できます。また、下記の情報が取得可能です。
|
||
Action権限 |
許可条件 |
user |
ユーザー情報が取得できます。 |
session |
セッション情報が取得できます。 |
||
action |
Action名が取得できます。 |
||
parameter |
リクエストパラメータの値が取得できます。 |
||
request |
リクエストの情報が取得できます。 |
||
WebApi権限 |
許可条件 |
user |
ユーザー情報が取得できます。 |
session |
セッション情報が取得できます。 |
||
webApi |
WebApi名が取得できます。 |
||
parameter |
リクエストパラメータの値が取得できます。 |
||
request |
リクエストの情報が取得できます。 |
||
Workflow権限 |
許可条件 |
user |
ユーザー情報が取得できます。 |
session |
セッション情報が取得できます。(バッチなど、APサーバ経由の起動以外の場合はバインドされません。) |
||
workflow |
workflow名が取得できます。 |
||
parameter |
リクエストパラメータの値が取得できます。 |
4.2. PreparedQuery形式
PreparedQuery(GroovyTemplate)形式で条件を設定するEntityは以下になります。
Entity | 設定項目 | バインド変数 | バインド内容 |
---|---|---|---|
Entity権限 |
参照可能範囲条件 |
user |
ユーザー情報が取得できます。 |
session |
セッション情報が取得できます。(バッチなど、APサーバ経由の起動以外の場合はバインドされません。) |
||
Cube権限 |
参照可能範囲条件 |
user |
ユーザー情報が取得できます。 |
session |
セッション情報が取得できます。(バッチなど、APサーバ経由の起動以外の場合はバインドされません。) |
特定のグループに対応した条件が必要で、範囲条件内に直接グループコードを記述する必要がある(環境に依存する自動採番のoidでは無く、固定値のグループコードを利用したい)場合、toGroupOidを利用した下記コードが利用可能です。
groups.oid in (${toIn(toGroupOid(['G01','G02']))})
ユーザーの所属グループのoidを直接利用したい場合は"user.groupOid"等をご利用下さい。
4.3. 特殊なバインド変数
バインド変数の利用方法、書式について説明します。
ユーザー情報
ユーザーに紐づく情報は条件式内で user.プロパティ名
と記述することで利用可能です。
例えば、 user.accountId
でユーザーの accountId
が取得できます。
GroovyScript形式の場合は user.プロパティ名
で取得可能です。
PreparedQueryの場合は ${user.プロパティ名}
と変数を ${}
で囲う必要があります。
ユーザーEntityに設定済のプロパティ以外にも取得可能な情報は以下になります。
プロパティ名 | 内容 |
---|---|
admin |
Admin権限をもつユーザー場合 |
temporary |
temporaryユーザーの場合 |
anonymous |
anonymousユーザーの場合 |
localAdmin |
共有テナント時のみ有効で、紐づいているテナントでAdmin権限を持つユーザーの場合は |
otherTenant |
共有テナント時のみ有効で、他テナントに紐づくユーザーの場合は |
tenantId |
テナントIDが返却します。 |
groupCodeWithChildren |
所属するグループの子グループも含めグループコードを返却します。 |
groupCodeWithParents |
所属するグループの親グループも含めグループコードを返却します。 |
groupOidWithChildren |
所属するグループの子グループも含めoidを返却します。 |
groupOidWithParents |
所属するグループの親グループも含めoidを返却します。 |
groupOid |
属しているグループ情報全てを配列で返却します。 |
また、 user.memberOf
という関数が利用できます。
項目名 | 内容 |
---|---|
memberOf(グループコード) |
対象グループに属している場合は |
リクエスト情報
アプリ側でログイン時や任意の処理等でパラメータにセットした値を取得する事が可能です。
def value = parameter.パラメータ名
def value = parameter.getValue("パラメータ名")(1)
1 | パラメータ名に"."が含まれている場合に利用されることを想定 |
また、下記のようにin句を利用可能です。 この場合、defNameがHogeEntityもしくはFugaEntityだった場合にtrueが返ります。
parameter.in('defName', 'HogeEntity', 'FugaEntity')
セッション情報
アプリ側でログイン時や任意の処理等でセッションにセットした値を取得する事が可能です。
def value = session.項目名;
def value = session.getAttribute("項目名");(1)
1 | 項目名に"."が含まれている場合に利用されることを想定 |
4.4. カスタム処理の利用
独自で作成したユーティリティクラス等をインポートし利用する事が可能です。 複雑な処理で抽出した条件をwhere句としたい場合等に利用して下さい。
例えば、 org.iplass.sample.SampleUtil
クラスを利用したい場合は以下のように記述します。
インポートの仕方がGroovyScript形式と、PreparedQuery(GroovyTemplate)形式で異なります。
-
GroovyScript形式の場合
import org.iplass.sample.SampleUtil; return SampleUtil.isAccess();
上記のような条件をAction権限に設定することで、Action権限の制御をユーティリティクラスで制御できます。
-
PreparedQuery(GroovyTemplate)形式の場合
<%@import org.iplass.sample.SampleUtil%> <% String tempOid = SampleUtil.getOid(); %> oid = ${tempOid}
TestUtilクラスのgetOid()メソッドにより返却されるoidを条件としたEQLとなります。
5. 特殊な権限の利用
5.1. 特権実行
Action、WebApiに対して、特権を設定する事が可能です。
特権実行とは、対象Action、WebApiの実行を、セキュリティの制約を一切受ける事なく実行可能にするものです。
また、Action、WebApiの実行を特権実行にせずに、実行されるロジックの一部のみを特権として実行する事も可能です。
この場合は下記のように AuthContext.doPrivileged
を利用します。
import org.iplass.mtp.auth.AuthContext;
AuthContext.doPrivileged(()-> {
・・・・・
});
EntityのLoad処理を特権実行で実行する場合の例を示します。
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.auth.AuthContext;
import org.iplass.mtp.entity.Entity;
import org.iplass.mtp.entity.EntityManager;
final EntityManager em = ManagerLocator.manager(EntityManager.class);
//特権でload処理を実行
Entity entity = AuthContext.doPrivileged(()-> {
return em.load("012345", "SampleEntity001");
});
Command内で検索は通常に処理し、更新は特権で実行する場合の例を示します。 更新部分のみを特権実行にすることで、必要最低限の特権実行とすることが出来ます。
public final class PrivelegeSampleCommand implements Command {
@Override
public String execute(RequestContext request) {
final EntityManager em = ManagerLocator.manager(EntityManager.class);
// 通常検索
final Entity entity = em.load("012345", "SampleEntity001");
entity.setDescription("sample description");
// 更新は特権で実行
AuthContext.doPrivileged(()->{
UpdateOption option = new UpdateOption();
option.add("description");
em.update(entity, option);
});
return "SUCCESS";
}
}