Auth0のトークンにRulesでロールを追加できなくなってハマった件

こんにちは、おんずです。
この記事はQiitaエンジニアフェスタ2021のAuth0のやつです。

https://qiita.com/official-events/5fcd3867b233a9228fd0

本日ですが、Auth0で設定を変えたことによって以前とは違う挙動になったことを書いていこうと思います。

## トークンにユーザーロールを追加するには

ユーザー設定でロールを追加しておきます。

![スクリーンショット 2021-07-26 8.54.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435/f8d6eda4-129d-c029-b86f-ef7995430752.png)

この追加したロールをトークンに追加するには、
ドキュメントにも記載がある通り、認証フローをカスタマイズできるRulesを使用して追加することが可能です。

https://auth0.com/docs/authorization/sample-use-cases-rules-with-authorization#add-user-roles-to-tokens

Ruleのサンプルコード

```javascript
function (user, context, callback) {
  const namespace = 'http://example.com';
  const assignedRoles = (context.authorization || {}).roles;

  let idTokenClaims = context.idToken || {};
  let accessTokenClaims = context.accessToken || {};

  idTokenClaims[`${namespace}/roles`] = assignedRoles;
  accessTokenClaims[`${namespace}/roles`] = assignedRoles;

  context.idToken = idTokenClaims;
  context.accessToken = accessTokenClaims;

  callback(null, user, context);
}
```

このような　Rulesを有効にしてAuth0でログインすると、Id Tokenには以下のようにカスタマイズされたものが返ってきます。　

サンプルコードにある`context.authorization`には
`{ roles: [ 'study-archive-admin' ] }`が入っていました。

```json
{
  "http://example.com/roles": [
    "study-archive-admin"
  ],
  "given_name": "******",
  "family_name": "******",
  "nickname": "******",
  "name": "******",
  "picture": "******",
  "locale": "ja",
  "updated_at": "2021-07-25T23:50:30.712Z",
  "email": "******",
  "email_verified": true,
  "sub": "******"
}
```

## 変更したAuth0の設定

上記のRulesが問題なく動作していましたが、別の組織（グループ会社）の人もログインできるようにするというアップデートをしようと思い、Auth0のOrganizationsを設定していくことにしました。

https://auth0.com/docs/organizations

ドキュメント通りにOrganizationsを作成し、Connectionsを設定しました。
Applicationsの設定もOrganizationsに合わせた設定に変更します。

![スクリーンショット 2021-07-26 9.16.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435/3acbf17b-73ce-b599-9636-6a3a9b3b2bf8.png)

- What types of end-users will access this application?
    - アプリケーションにログインするユーザーのタイプを制御する
        - 今回は組織のメンバーしかログインできない設定にした
- Display Organization Prompt
    - ログインする前にユーザーに組織名の入力を求めるかどうか
        - 今回は有効にした

Organizationsを有効にし、アプリケーションにログインすると、`org_id`がID TOKENに追加されていました。
アプリケーションではこのIDを使い組織名を表示したり、トークンの検証を行ったりします。

```json
{
  "given_name": "******",
  "family_name": "******",
  "nickname": "******",
  "name": "******",
  "picture": "******",
  "locale": "ja",
  "updated_at": "2021-07-25T23:50:30.712Z",
  "email": "******",
  "email_verified": true,
  "sub": "******",
  "org_id": "org_6lW5aSNUAlGDVl49"
}
```

と、ここまで設定は良さそうだなと思っていたのですが、Rulesで追加されるはずのRoleがないことに気づきます。
※ Roleで表示できるページをチェックしていたのでアプリではエラーが出ました。
なんでや？？？

## 調べてみる

とりあえずRulesのデバッグ機能を利用し、書いたRuleが動いているか確認しましたが、ちゃんと動いていました。
(console.logで出力させた)

ところが、`context.authorization`にあったrolesがなくなっている。。。

※  デバッグログの中身　
![スクリーンショット 2021-07-26 9.38.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435/f04b7282-0253-7dfd-4051-eb940c465d28.png)

ユーザーのRoleはサインアップ時に自動で付くようにしており、`Users->Roles`を見るとちゃんと追加されていました。

ドキュメントを漁るかと思い、Organizationのところを見ていると、`Add Roles to Organization Members` というページにたどり着きました。

https://auth0.com/docs/organizations/add-member-roles

organizationsのメンバーにRoleを追加するという機能で、あらかじめRoleは作成しておくとのこと。

とりあえず設定してみよう。

![スクリーンショット 2021-07-26 9.54.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435/69730862-1ac7-9dd4-e144-1688b5867510.png)

メンバーの設定箇所に`Assign Roles`というのがあるのでクリック。

![スクリーンショット 2021-07-26 9.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435/9000ebf7-3632-ef17-743f-f726229c391a.png)

追加したいロールを選択して保存して追加完了となります。

この状態で再度アプリケーションにログインすると、

なんということでしょう

デバッグログを確認すると`context.authorization`に　Role がちゃんと追加されていました。

![スクリーンショット 2021-07-26 9.59.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435/3ab4fc12-db92-ebfc-891a-1845cadd4e92.png)

もちろんID Tokenにもちゃんと追加されていました。

## 今回の現象のまとめ

- Rulesでトークンにユーザーに付けられているRoleが追加されるように構成していた
    - `context.authorization`　を使用してRoleを取得　
- アプリケーションの設定でorganizationsのメンバーしかアクセスできないようにした
- この状態でログインするとトークンにユーザーに付けられているRoleが追加されず
- organizationsのメンバーにRoleを追加する設定を行うと意図通りにRoleが追加された

といった感じでした。

organizationsを使用すると
`context.authorization`がユーザーに紐づいているRoleではなく、organizationsのメンバーに紐づいている　Roleを参照するようになるとは思いませんでした。
※ この辺りのこはドキュメントに記載されいるのかどうか見つけられていません。知っている人がいれば教えていただきたいです

organizationsを使わず運用していて、途中から使うときは注意が必要ですね。