はじめに
ある程度以上の規模の会社やサービスでAuth0を使っていると、Auth0に対する権限を担当者ごとに分けたいというニーズが出てくるかと思います。例えば、以下の三者の役割ごとに権限を分けるといった場合です。
- Auth0のテナント管理者
- Auth0を利用するアプリの開発者
- エンドユーザーからの問い合わせを受け付けるヘルプデスク
Auth0のテナント管理者はテナントを作成したユーザーなので問題ないと思います。あとでテナント設定からAll Applicationsの権限を持たせてユーザーをテナントに招待することも可能です。Auth0を利用するアプリの開発者についても同様で、開発者をテナントに招待するときに任意のアプリのみに権限を絞ることで、そのアプリの設定以外は触れなくなるので、こちらも特に問題ないと思います。
しかし、ヘルプデスクの権限を考えるとちょっと悩ましいです。
ヘルプデスクの担当業務範囲にもよりますが、エンドユーザーからの問い合わせを受け付けるという業務の特性上、Auth0に登録されているユーザーの情報やログが見れた方が良い場合もあると思います。しかし、ヘルプデスクの担当者にはアプリの設定を変更できるような権限は付与したくありません。Auth0の管理DashBoard(テナント管理画面)だけでこういった要件を実現するのは難しいです。
ユーザー管理やログを見るためだけのWebアプリを作り、Management APIで必要な情報を引っ張ってきて頑張る。というのも一つの手ですが、Auth0にはまさにこの要件を叶える「Delegated Admin DashBoard」という拡張機能があります。この拡張機能を使ってユーザー情報・ログを見ることができるDashBoadを作成したので、その機能と作成(設定)方法とを紹介します。以降、このDashBoardのことをDelegated Admin DashBoardと表記します。
Delegated Admin DashBoardでできること
ユーザー管理
ユーザー一覧の参照や、ユーザーの作成・更新・削除を行うことができます。
後述するロールの設定にもよりますが大雑把に以下のような操作が可能です。
- ユーザーの検索
- ユーザー情報の閲覧
- ユーザーの作成
- ユーザーのブロック
- パスワードリセット(メール送信)
- 確認メール再送信
- メールアドレス変更
- パスワード変更
- ユーザーの削除
Auth0の管理DashBoardからできることとは微妙に違うので、詳細は以下のAuth0のドキュメントを参照してください。
ログ閲覧
ログの一覧とログの詳細(json形式)を見ることができます。
しかし、Auth0の管理DashBoardほど過去のログは表示してくれないようです。
Hookの設定
Delegated Admin DashBoardの動作をカスタマイズするHookを設定することができます。
後述の「Delegated Admin - Administrator」のロールを持つユーザーがHookを設定することができます。Hookの設定メニューはDelegated Admin DashBoardの右上に表示されているテナント名をクリックすると表示されるドロップダウンメニューから選択できます。
Hookには以下の4種類があり、それぞれ用途が異なります。
- Fileter Hook
- Access Hook
- Write Hook
- Memberships Hook
- Settings Query
Hookを使えばデフォルトのロール設定だけでは対応できない細かい権限設定も可能になります。
Delegated Admin DashBoardの設定
アプリケーション登録
Auth0のドキュメントに書いてある通り、Delegated Admin DashBoardをアプリケーション登録します。
Create Delegated Admin Applications
アプリケーションタイプは「Single Page Web Applications」を選択してください。
次に、登録したアプリのCallback Allowed Callback URLsとAllowed Logout URLsを設定します。設定するURLはテナント名やテナントのリージョンごとに異なるので適切な値を設定してください。
設定項目 | 値 |
---|---|
Allowed Callback URLs | https://{xxx}.{yy}8.webtask.io/auth0-delegated-admin/login |
Allowed Logout URLs | https://{xxx}.{yy}8.webtask.io/auth0-delegated-admin |
{xxx}にはAuth0のテナント名が入ります。テナントのドメインがabc.auth0.comなら、{xxx}に入るのはabcになります。また、{yy}にはリージョンごとの固有の値が入ります。具体的な値は先に記載したAuth0のドキュメント(Create Delegated Admin Applications)に載っているのでそちらを参照してください。
自分のテナントはUSリージョンなので以下のように設定しています。
2020/5/19 追記
Auth0でNode.js 12がサポートされるようになりました。
ランタイムをNode.js 12に切り替えた場合、以下のようにCallback URLとLogout URLを変更する必要があります。
設定項目 | 値 |
---|---|
Allowed Callback URLs | https://{xxx}.{yy}12.webtask.io/auth0-delegated-admin/login |
Allowed Logout URLs | https://{xxx}.{yy}12.webtask.io/auth0-delegated-admin |
参考:Migration Guide: Extensibility and Node 12 #delegated-administration-urls
データベース接続の作成
Delegated Admin DashBoardを利用するユーザーを管理するための新しいデータベースを作成します。
Auth0の管理DashBoardのConnections > Database
を選択し、「CREATE DB CONNECTION」ボタンをクリックします。本記事ではデータベースをHelpDeskという名前で作成しています。
ここで作成したデータベースはDisable Sign Upsの設定をONにします。この設定でサインアップを無効化しておかないと、サインアップすれば誰でもDelegated Admin DashBoardを利用することができてしまうからです。このデータベースへのユーザー追加はAuth0のテナント管理者のみが行うようにしましょう。
このデータベースはDelegated Admin DashBoard(と後述するauth0-delegeted-admin
)以外のアプリからは利用しないので、作成後にデータベースの設定画面からApplicationsタブを選択し、Delegated Admin DashBoard以外のアプリとの接続設定がされていないことを確認してください。
デフォルトのテナント設定だと、新しいアプリがAuth0に登録されるたびに全てのデータベースとの接続が有効になってしまいます。今後、アプリ登録を行うと意図しないアプリがここで作成したデータベースと接続してしまう可能性があるので注意してください。
もしも支障がないのであればテナント設定のほうを変えてしまって、アプリ登録時に勝手にデータベースと接続しないようしたほうが良いと思います。Tenant Settings > Advanced
のメニューから、Enable Application Connections
の項目をOFFにすることで設定できます。
ただし、この項目をOFFにするとアプリを登録してもデータベースと自動的に接続されなくなるので、今度は逆に接続先データベースを設定する手間が毎回発生するようになります。
DashBoadを利用するユーザーの作成
Delegated Admin DashBoard用に作成したHelpDeskデータベースにAuth0の管理DashBoardからユーザーを追加します。
Users & Roles > Users
の画面から「CREATE USER」ボタンをクリックしてユーザーを登録します。Connection
が先に作成したHelpDeskデータベースであることを確認して登録してください。
ロールの作成と割り当て
Delegated Admin DashBoardはユーザーのロールに基づいて利用できる機能を制限しています。Delegated Admin DashBoard固有のロール定義は既に決まっているので、それに沿うようにロールの作成とユーザーへの割り当てを行います。
作成するロールは以下の4つです。この名称のロールしかDelegated Admin DashBoardは受け付けないので、このままの名称でロールを作成してください。
名称 | できること |
---|---|
Delegated Admin - Administrator | Delegated Admin DashBoardでできる全ての操作が可能 |
Delegated Admin - User | ユーザーに関する操作は一通り可能。ログ閲覧とHookの設定は不可 |
Delegated Admin - Auditor | ユーザー情報の閲覧のみ可能。 |
Delegated Admin - Operator | ログの閲覧のみ可能 |
Users & Roles > Rolesの画面の「CREATE ROLE」ボタンをクリックしてロールを4つ作成します。
※作成したロールには個別にPermissionをつけることが可能ですが、Delegated Admin DashBoardを利用する上では設定不要です。
あとは作成したロールの中から適当なのを選んで、先ほど作成したユーザーにロールを割り当てます。
Rulesの作成
ユーザーがDelegated Admin DashBoardにログインしたときのIDトークンに、ロールの情報を追加するために以下のRulesを設定します。
function (user, context, callback) {
if (context.clientID === '{CLIENT_ID}') {
const namespace = 'https://example.com/auth0-delegated-admin';
context.idToken[namespace] = {
roles: (context.authorization || {}).roles
};
}
callback(null, user, context);
}
{CLIENT_ID}はアプリ登録したDelegated Admin DashBoardのクライアントIDに置き換えてください。
namespace
のhttps://example.com/auth0-delegated-admin
はこのまま設定してください。でないとDelegated Admin DashBoardが認識してくれません。
拡張機能のインストール
ここまできてようやく拡張機能のインストールです。
Auth0の管理DashBoardのExtensionsからDelegated Admin DashBoard
を探してインストールします。インストール時に設定を聞かれるのでEXTENSION_CLIENT_ID
に先ほどアプリ登録したDelegated Admin DashBoardのクライアントIDを設定します。他の項目は必要に応じて設定してください。
拡張機能インストールが完了するとApplicationsにauth0-delegated-admin
が追加されます。これはDelegated Admin DashBoardがManagement APIを利用するために必要な設定みたいなので、下手に触らない方が無難です。
この拡張機能をインストールするとApplicationsにauth0-delegeted-admin
というアプリが自動的に登録されます。Delegated Admin DashBoardからユーザー作成、更新、削除などを実施する場合は、その対象ユーザーが保存されているデータベースに、このauth0-delegeted-admin
からも接続できなければならないので、必要に応じてConnections
の設定から接続するデータベースをONにしてください。
Delegated Admin DashBoardにアクセス
Auth0の管理DashBoardのExtensions
からInstalled Extensionsのタブを選択すると、先ほどインストールしたDelegated Administration Dashboardが表示されます。
この「Delegated Administration Dashboard」の文字列をクリックすると、ログイン画面が表示されるので、Delegated Admin DashBoardの利用ユーザーとして登録したメールアドレスとパスワードを入力してログインをします。
以下のような画面が表示されれば成功です。
このDelegated Admin DashBoardから先に述べたユーザー管理、ログ閲覧、Hookの設定を行うことができます。
Hook
Auth0のドキュメントにサンプルが記載されていますが、自分でも少し試してみたのでそのコードを載せておきます。
Filter Hook
Filter Hookを利用するとDelegated Admin DashBoardに表示されるユーザーをクエリで制御することができます。
Delegated Administration Hooks: The Filter Hook
function(ctx, callback) {
var namespace = 'https://example.com/auth0-delegated-admin';
var userRoles = ctx.request.user[namespace] && ctx.request.user[namespace].roles;
if (!userRoles || !userRoles.length) {
return callback(new Error('Unauthorized error.'));
}
if (userRoles.includes('Delegated Admin - Administrator')) {
return callback(null);
}
return callback(null, '- identities.connection:"HelpDesk"');
}
```
`Delegated Admin - Administrator`のロールを持たない人はDelegated Admin DashBoardからHelpDeskデータベースに登録されているユーザーが表示されないようにしています。callbackの第二引数に設定するクエリは`Lucene Query`という構文が使用できます。
[LuceneTutorial.com](http://www.lucenetutorial.com/lucene-query-syntax.html)
### Access Hook
Access Hookを設定するとDelegated Admin DashBoardに表示されているユーザーに対する操作を検知して任意のコードを実行することができます。
[Delegated Administration Hooks: The Access Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/access)
```javascript
function(ctx, callback) {
var namespace = 'https://example.com/auth0-delegated-admin'
var userRoles = ctx.request.user[namespace] && ctx.request.user[namespace].roles;
if (!userRoles || !userRoles.length) {
return callback(new Error('Unauthorized error.'));
}
switch (ctx.payload.action) {
case 'delete:user':
return callback(new Error('Unauthorized error.'));
case 'change:email':
if (!userRoles.includes('Delegated Admin - Administrator')) {
return callback(new Error('Unauthorized error.'));
}
return callback();
default:
return callback();
}
}
```
Delegated Admin DashBoardからはユーザーの削除は不可、emailの変更は`Delegated Admin - Administrator`のロールを持っている人のみ可能。としています。
### Write Hook
Write Hookはユーザーの作成やカスタムフィールドの更新をしたときに実行されるコードを設定できます。
[Delegated Administration Hooks: The Write Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/write)
```javascript
function(ctx, callback) {
var newProfile = {
email: ctx.payload.email,
password: ctx.payload.password,
connection: ctx.payload.connection,
user_metadata: ctx.payload.user_metadata,
app_metadata: {
department: ctx.payload.memberships && ctx.payload.memberships[0],
...ctx.payload.app_metadata,
},
};
if (ctx.method === 'update') {
Object.keys(newProfile).forEach((key) => {
if (newProfile[key] === ctx.request.originalUser[key]) delete newProfile[key];
});
}
const whitelist = ['example.com', 'example.co.jp'];
const userHasAccess = whitelist.some(
(domain) => {
const emailSplit = ctx.payload.email.split('@');
return emailSplit[emailSplit.length - 1].toLowerCase() === domain;
},
);
if (!userHasAccess) {
return callback(new Error('Access denied.'));
}
return callback(null, newProfile);
}
```
`example.com`または`example.co.jp`以外のドメインのメールアドレスのユーザーを作成できないようにしています。ただ、このコードだとメールアドレスの変更まではブロックできないのでRoleやAccess Hookなどと組み合わせてメールアドレスの変更自体をできないようにしないと、このコードの使い所は無いと思います。
### Memberships Hook
Membership Hookのcallback関数に配列を渡すとDelegated Admin DashBoardからユーザーを作成するときに部署名(Membership)のフィールドが表示されるようになり、プルダウンで配列の内容を入力できるようになります。(配列の要素が一つだけだと部署名フィールドも表示されません。)
[Delegated Administration Hooks: The Memberships Query Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/membership)
```javascript
function(ctx, callback) {
var namespace = 'https://example.com/auth0-delegated-admin';
var userRoles = ctx.payload.user[namespace] && ctx.payload.user[namespace].roles;
if (!userRoles || !userRoles.length) {
return callback(null, []);
}
if (userRoles.includes('Delegated Admin - Administrator')) {
return callback(null, ['IT', 'HR', 'Finance', 'Marketing']);
}
return callback(null, [ctx.payload.user.app_metadata.department]);
}
```
`Delegated Admin - Administrator`のロールを持つ人にのみ、以下のように部署名(Membership)フィールドが表示しています。
![スクリーンショット 2020-03-16 17.14.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490013/0cd384e0-9aa1-b67a-270d-ed99adb93e93.png)
### Settings Query
Setting Queryを利用するとDelegated Admin DashBoardのLook and Feelをカスタマイズすることができます。
[Delegated Administration Hooks: The Settings Query Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/settings)
```javascript
var namespace = 'https://example.com/auth0-delegated-admin';
var userRoles = ctx.request.user[namespace] && ctx.request.user[namespace].roles;
var isAdmin = userRoles.includes('Delegated Admin - Administrator');
return callback(null, {
connections: ['Username-Password-Authentication'],
canCreateUser: isAdmin,
});
```
`connections`でDelegated Admin DashBoardからユーザーを登録するときの登録先データベースを`Username-Password-Authentication`だけに限定しています。さらに`canCreateUser`で`Delegated Admin - Administrator`のロールを持つ人だけにユーザー作成のボタンが表示されるようにしています。
## まとめ
Auth0の拡張機能である「Delegated Admin DashBoard」を使うとユーザー管理やログの閲覧が出来るDashBoardが簡単に作成できます。
RoleとHookを組み合わせて利用することで細かい権限管理も実現できそうなので、担当者の役割に応じてAuth0の管理DashBoardとDelegated Admin DashBoardを使い分けるという運用も可能だと思います。是非試してみてください。
## 参考にしたAuth0のドキュメント
[Delegated Administration Extension](https://auth0.com/docs/extensions/delegated-admin/v3)
[Create Delegated Admin Applications](https://auth0.com/docs/dashboard/guides/extensions/delegated-admin-create-app)
[Install the Delegated Admin Extension](https://auth0.com/docs/dashboard/guides/extensions/delegated-admin-install-extension)
[Use the Delegated Admin Extension](https://auth0.com/docs/dashboard/guides/extensions/delegated-admin-use-extension)
[Delegated Administration: Manage Users](https://auth0.com/docs/extensions/delegated-admin/v3/manage-users)
[Delegated Administration: Hooks](https://auth0.com/docs/extensions/delegated-admin/v3/hooks)
[Delegated Administration Hooks: The Filter Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/filter)
[Delegated Administration Hooks: The Access Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/access)
[Delegated Administration Hooks: The Write Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/write)
[Delegated Administration Hooks: The Memberships Query Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/membership)
[Delegated Administration Hooks: The Settings Query Hook](https://auth0.com/docs/extensions/delegated-admin/v3/hooks/settings)