🛡️

Auth0 Organizationsという素晴らしい機能を今更ながら紹介する

2021/11/13に公開
1

はじめに

Auth0いいですよね!
認証/認可をほとんどおまかせすることができて、ログインページも作ってくれるし、セッション管理もしてくれる。SPAでも。SDKで簡単にトークンの更新をiframeでよしなにやってくれたりと、かなり神ががっているIDaaSです。

そんなAuth0にOrganizationsという機能が2021年4月にリリースされていました。

最近はReactを触ったり、Kotlinを触ったりと全然別のことばかりしていたので、キャッチアップが遅れてしまったのですが、色々試したりして、辛かったマルチテナントの認証/認可が簡単になる可能性を多大に感じたのでまとめてみました。

ただ、もう少しコレがあれば...!と思う点もあったので、そこも踏まえてご紹介していきます。

※ Auth0をちょっと知っている人向けに書くので、細かい用語の説明は入れません

Auth0 Organizationsとは

Auth0 Organizationsとは、Auth0上にエンドユーザーの組織(Organization)を作成する機能です。
https://auth0.com/docs/organizations

Organizationには、Auth0上のユーザーを追加することができ、Organizationに所属するユーザーに対してそのOrganization内で有効な権限を付与することができます。

このように、Auth0 Organizationsはマルチテナントの認証/認可の際に本領を発揮します。
一人のユーザーが複数のテナントに所属するようなユースケースに対しても、簡単に対応することが可能になります。

Auth0 Organizationsが出る前は...

Auth0 Organizationsが出る前は、マルチテナントの認証/認可を実装するのは複雑で、いくつか手段があり、ユースケースに合わせて選択する必要がありました。
また、Auth0の標準機能だけでマルチテナント認証/認可機構を構築できる訳ではなく、Auth0 Rulesを利用して拡張する必要があったり、アプリケーション側で制御するなどの工夫が必要でした。

↓はAuth0 Organizations以前のマルチテナント関連の参考記事です。

とはいえ、ユーザーが一つのテナントにしか所属しないシンプルなユースケースであれば、多少の拡張で済むので、そこまで問題にはならなかったと思います。

一方で、NotionやGCPのように、ユーザーが複数のテナントに所属するようなユースケースを実現するのは、かなり骨が折れる拡張作業が必要になります。
特に、RBACのような認可の仕組みを入れようとすると、Auth0単体だとかなり難しくなってきます。

過去に、ユーザーが複数のテナントに所属し、かつ、複数のプロダクトを利用するユースケースの認証/認可部分をAuth0を使って構築したことがありますが、正直かなり辛かったです。

Auth0 Organizationsで認証する

さて、ようやく本題に入れます。
ここからは、Auth0 Organizationsを使って実際にマルチテナント認証/認可基盤を構築することで、「Auth0 Organizationsすごいじゃん!」っていうのをお伝えできればと思います。

まずは、認証からです。
ユーザーがOrganizationにログインするまでをDemoアプリを作成して構築します。

1. Organizationの作成

最初にOrganizationを作成しましょう。
サイドバーから、「Organizations」を選択し、「Create Organization」をクリックします。

「Name」と「Display Name」を入力します
「Name」には、小文字アルファベットと数字とアンダースコアのみ使用出来ます。
この「Name」は、ログイン時にユーザーがどのOrganizationにログインするのかの判別に使用します。

次に、作成したOrganizationにコネクションを追加します。
「Connection」タブに移動して「Enable Connections」をクリックします。
今回はとりあえずDatabaseコネクションを追加します。

現時点ではこのOrganizationには誰も所属していないため、このOrganizationにログインできる人は存在しません。

2. ユーザーの追加

ログイン可能なユーザーが一人もいないので、サンプルユーザーを作成して、1.で作成したOragnizationに追加しましょう。
サイドバーの「User Management > Users」を選択し、「Create User」をクリックします。

では、作成したユーザーをOrganizationに追加します。

1.で作成したOrganizationに戻り、「Member」タブを移動して「Add Member」をクリックします。
おそらく初期状態では「No users matching search」と出て、選択可能なユーザーが出てこないです。
メールアドレスを入力すると、ユーザーを選択することができるようになります。

3. Applicationの作成

Organizationにログインする準備が整ったので、サンプル用のApplicationを作成しましょう。
デモアプリをReactにする予定なので、 Single Page Application を選択してください。

「Allowed Callback URLs」に http://localhost:3000 を設定して保存しておいてください。

次に、作成したApplicationのOrganizationタブに移動してください。
初期設定では、「個人ユーザー」のみログイン可能になっていますので、Team members of organizationsに変更してください。
更に「Display Organization Prompt」をONにしてください。
こうすることで、ログイン前に自動的にどのOrganizationにログインするか選択するページに遷移するようになります。

4. デモ用アプリの作成

作成したアプリケーションのQuickStartタブからReactを選択し、サンプルをダウンロードしてください。
https://auth0.com/docs/quickstart/spa/react/01-login

ダウンロードが完了したら、sh ./exec.sh を実行し、http://localhost:3000 にアクセスしてください。

すると、以下のような画面が出るはずです。

この状態で「Log In」ボタンを押すと、以下のような画面が出るはずです。
ここに、1.で作成したOrganizationの「Name」を入力します。

そうすると、いつものログイン画面が表示されるはずです。
2.で作成したユーザーでログインすると、ログインに成功するはずです。

ちなみに、このログイン画面はOrganizationごとにカスタマイズすることが可能です。

まとめ

以上で、Auth0 Organizationsを使って認証をすることが出来ました。
今回は1 Organization, 1 Userしか作成しなかったので分かりづらかったですが、Organizationを複数作成するとOrganizationsの強みがハッキリ見えてくると思います。

Organizationsを使わない場合との差異は、大きく以下の2点です

  1. UserをOrganizationに追加する必要がある
  2. ログイン前にOrganizationのNameをユーザーに入力してもらう必要がある

Organization Nameの入力に関しては、3.で設定した「Display Organization Prompt」をOFFにすると入力画面は出ません。
この場合、認証時のパラメーターにorg_idというキーでOrganizationのIDを渡す必要があります (Organization Nameとは異なりAuth0側で自動に割り振られるIDです)。
テナント毎にサーバーが別れている場合や、メールアドレスなどでorg_idが認証前に特定できるのであれば、「Display Organization Prompt」をOFFにして、ユーザーの入力を減らしてあげるとユーザーフレンドリーになりそうです。

「Display Organization Prompt」をONにしている場合は、入力するステップが増えるので、ユーザー体験的には微妙だと感じました (特にUserが1つのOrganizationにしか所属していないとき)。
この問題に関しては、Auth0 Actionsを使うことで、Organization Nameの入力をスキップしつつ、デフォルトのOrganizationでログインさせることができたので、別の記事でご紹介しようと思います。

Auth0 Organizationsで認可してみる

ここからより実践に近い認可をOrganizationで試してみます。
認可の手法にはRBAC(Role Base Access Control)を使用します。

0. ユースケース

React.jsのようなSPAではAPIサーバーを持っていることが多いと思います。
Auth0を使われているのであれば、Access TokenをAuth0から取得し、Authorizationヘッダーにsetして、APIサーバーで確認させるような構成になると思います。

マルチテナントのシステムを構築する前提で、Access Tokenに以下の情報を含めたいと思います。

  1. テナントID
  2. ユーザーID
  3. 権限

以上のユースケースをAuth0 Organizationsを使って構築してみましょう。

1. APIを作成する

Auth0でAccess Tokenを作成するためには、APIというエンティティを作成する必要があります。
Auth0ダッシュボードに戻り、サイドバーから「Applications > APIs」を選択し、「Create API」をクリックします。

適当な「Name」と「Identifier」を設定します。
「Identifier」はAccess Token取得時にaudienceとして指定する識別子になります。

「RBAC Setting」はどちらもEnableにしましょう。
こうすることで、Access TokenにRoleに紐づくPermissionが勝手に付与されます。

次に、「Permission」タブに移動して、適当はPermissionをいくつか作成してください。

2. Roleの作成

次に、ロールを作成します。
サイドバーの「User Management > Roles」を選択し、「Create Role」をクリックし、適当なロールを作成します。

作成したロールに1.で作成したPermissionを割り当ててください。

3. OrganizationのUserにRoleをAssignする

最後に、OrganizationのUser2.で作成したRoleをAssignします。
ここでAssignするRoleはこのOrganizationでログインした時のみ有効になります。

前節の1.で作成したOrganizationを選択し、「Member」タブに移動し、追加されているユーザーをクリックします。
すると、ユーザー詳細ページの右上に「Assign Roles」ボタンが現れるので、そいつをクリックして2.で作成したロールをAssignします。

これで準備は完了です。

4. Access Tokenを取得する

デモアプリに戻り、src/auth_config.jsonaudience1.で作成したAPIのIdentifierに書き換えて、sh exec.shを再実行してください。

再度ログインし、ヘッダーから「External API」ページを開いて、「Ping API」をクリックします。
この時、ブラウザのDeveloper Toolsで「Network」タブを開いて通信を除いてみると、http://localhost:3001にAPIリクエストが送られているはずです。
このリクエストのAuthorizationヘッダーを見てみると、JWTが入っているはずです。

このJWTをjwt.ioで確認すると、中にsuborg_idpermissionsというClaimが含まれているはずです。

まとめ

以上で、Organizationを使って認可を実現することができました。
認証と同じく、Organizationを複数作成して、ユーザーを複数のOrganizationに所属させるようにしたときに、Auth0 Organizationsの強みが見えてくると思います。

Auth0 Organizationsが出る以前は、ユーザーがログインするテナントに合わせてロールを取得しパーミッションをAccess Tokenに付与するAuth0 Rulesを作成することは可能でしたが、Auth0 APIsの仕組みを活用できていませんでした。
一方で、Auth0 Organizationsを使うとAuth0 Rulesなどを使って拡張せずとも、Auth0 APIsのRBAC機能を使ってAccess TokenにPermissionを付与することが可能になります。

総まとめ

Auth0 Organizationsを使ってマルチテナント認証/認可を試してみました。

メリデメをまとめてみます。

メリット

  • ユーザーが複数テナントに所属するマルチテナント認証・認可を簡単に構築できる
    • RBACを使った認可であれば、Ruleは不要
  • app_metadataで、ユーザーがどのテナントに所属しているか管理する必要がなくなる
    • テナントIDをAccess Tokenに追加するRuleも不要になる
  • Organizationに対してMetadataを設定することができる
    • IPアドレス制限など、テナント全体に有効化したRuleがある場合にとても強い

これまで触れてきませんでしたが、実はOrganizationに対してMedatadaを設定することができます。
このMedatadaはAuth0 ActionsやRulesから参照することが可能なので、Organizationのユーザー全体に対して何か有効にしたいようなユースケースでは多大な力を発揮します。

デメリット

  • ユーザーがログインする時の入力が増えてしまう
    • OFFにできる
    • 回避方法あり (別記事で紹介します)
  • Planによって作成できるOrganization数に上限がある
    • Free: -
    • Essentials: 50個
    • Professional: 100個
    • Enterprice: 制限なし

Organizationの作成上限についてはこれまで触れてきませんでしたが、テナント数が多いサービスにおいては大きな制約になりそうです。
Free PlanではAuth0 Organizationsが使えなさそうな表記がされているのですが、一応2021年11月段階では使えています。
とはいえ、そのうち使えなくなる可能性があるので、本番利用する際は少なくともEssentials以上にあげてあげたほうが良さそうです。

総じて、個人的にはマルチテナントなユースケースにおいては、Planの制限に引っかからないのであれば、積極的にOrganizationsを採用しても良いのではないかと思いました。

ログイン前にOrganization Nameを入力してもらうなど、微妙な点は存在しますが、新しい機能ですし、これからアップグレードされていくと思いますので、今後に期待です!

Discussion

satoppeppersatoppepper

とても参考になりました。
こちらの内容も心待ちにしています。よろしくお願いします。

Auth0 Actionsを使うことで、Organization Nameの入力をスキップしつつ、デフォルトのOrganizationでログインさせることができたので、別の記事でご紹介しようと思います。