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


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

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

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

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

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

Ruleのサンプルコード

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' ] }が入っていました。

{
  "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を設定していくことにしました。

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

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

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

{
  "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がなくなっている。。。

※ デバッグログの中身 

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

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

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

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

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

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

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

なんということでしょう

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

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

今回の現象のまとめ

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

といった感じでした。

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

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