26
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Auth0でSSOをどうやって実現しているか実験してみた

Posted at

はじめに

Auth0のUniversal LoginでSSOが実現できると公式ドキュメントに書いてありましたが、Application側のSession管理の方法や複数アプリケーションでログイン/ログアウトをした場合の動作など、詳細な仕組みが書かれていなかったので、QuickStartを使って簡単に実験してみました。

今回試したのは、Regular Web ApplicationとSingle Web Applicationです。
NativeとMachine to Machine Application (Shell Script)については試していません。

また、今回取り扱うのはUniversal Loginなので、埋め込みログイン方式のSSOについては触れません。
埋め込みログインがCross Originでの認証になるので、セキュリティーリスクがあったり、ネイティブでは実現不可能ということが書かれていましたが、なぜ不可能かまではわからなかったので、これは別記事で触れたいと思います。

TL;DR

  • REGULAR WEB APPLICATIONの場合、Session Cookieでログイン状態を管理
  • SINGLE PAGE APPLICATIONの場合、Cookieの認証済みフラグでログイン状態を管理
  • サイトAでログアウトしても、Sessionが生きてる限り、サイトBではログアウトされない

SSOとは

SSOはSingle-Sign-Onの略字です。
よく企業システムで複数のアプリケーションを利用する際に用いられる事が多いということもあり、SSOという言葉は知っているけど、何を指しているのか僕の中で曖昧だったので、改めて書いてみます。

僕の中の認識では、「一つのIDで複数のアプリケーションで認証ができる仕組み」です。
大体文字通りだと思いますが、一応例を出してみよおうと思います。

例えば、ある3つのアプリケーションApp1, App2, App3がある場合を考えてみます。

もし、SSOを使わない場合は、3つのアプリケーションで登録処理を行う必要があります。
そのため、アプリケーションごとにID/PWが必要になり、管理が煩雑になりやすいです。

一方で、SSOを使う場合、登録するのは一つのアプリケーションだけで、残りのアプリケーションは連携の許可だけで済みます。
そのため、複数アプリケーションがあったとしてもID/PWは一つだけになり、ユーザ目線から見ると管理が容易になります。

最近だと、GoogleログインやFacebookログインなどのソーシャルログインが流行っているのでイメージしやすいと思います。もちろんソーシャルログインもSSOの一つです。

SSOには色々な実装方法があるらしいのですが、それについてはまだ調べきれていないので、ここでは飛ばしたいと思います。

Auth0でのSSO

Auth0について簡単に説明すると、認証に特化したマネージドサービスです。いわゆるIDaaSってやつですね。
https://auth0.com/jp/

Auth0には、Universal Loginと呼ばれるログイン方式が存在します。
大まかな仕組みは下の埋め込みログインとの比較図を見てもらうと想像がつくと思います。
image.png
https://auth0.com/docs/guides/login/universal-vs-embedded

Universal Login(左図)はAuth0がHostingするサーバーで認証を行い、各アプリケーションへリダイレクトする方式をとっています。なので、ログインしたときのセッションはAuth0ドメインのSession Cookieとして保管されます。

一方で、埋め込みログイン(右図)の方は各アプリケーション内で認証を行うため、ログインセッションは各アプリケーションで持つことになります。
埋め込みログインでSSOを行う場合は、Third Paty Cookieに認証状態が保管されるというふうにドキュメントには書かれていましたが、実際に試してはいないので、詳細な動きは不明です。

ここまでは大体想像がつくと思うのですが、Central Loginの場合、アプリケーション側のログイン状態の管理をどのように行っているのかドキュメントからはわからなかったので、実際にアプリケーションを立てて試してみました。
検証用に立てたアプリケーションは以下の2つです。どちらもAuth0のQuickStartを用いました。

  1. Laravel製の一般的なWeb Application
  2. React製のSingle Page Application

1. Laravel製の一般的なWeb Application

image.png

このQuickStartの通りに進めていきます。
Auth0のQuickStartの良いところは、ログインしていれば、Auth0のクライアントIDやエンドポイントなどの情報が埋め込まれたサンプルアプリケーションをzipファイルでダウンロードすることができることです。

Auth0側の設定

Auth0へログインし、ダッシュボードへ移動します。
サイドバーのApplicationsを選択し、CREATE APPLICATIONをクリック。
下記図のように、Application名を入れて、「Regular Web Applications」を選択し、CREATEをクリックします。

image.png

Applicationの作成が完了したら、以下図のように Allowed ***となっている項目に http://localhost:3000を追加します。
これを設定しないと、うまくリダイレクトされなくなります。

また、Allowed Callback URLsは、http://localhost:3000/callbackに設定します。
(Callback URLはLaravelサンプル内の.envに書いてあるで、もし異なっていたら.envの設定を書きます。)

image.png

Laravel編

具体的な手順とDockerでの開発環境構築を書きます。

  1. 「LOG IN & DOWNLOAD SAMPLE」をクリックし、Applicationを選択
  2. 「DOWNLOAD」をクリックし、サンプルをダウンロード
  3. 適当な位置に配置
  4. 解凍&実行
unzip laravel-01-login.zip
cd 00-starter-seed
sh exec.sh

これだけです。

exec.shを実行すると、docker上にlaravelのWebサーバコンテナを起動してくれます。
composer installartisan周りの初期化もしてくれるので楽ちんですね。

サーバー起動後は http://localhost:3000 に接続するとWebページを見ることができます。

image.png

右上のサイドバーにLoginボタンがあるのでクリックしてみます。
すると、以下のような {tenantID}.auth0.comのページに飛ばされます。

image.png

このページでログインしてみます。
すると、図のような感じでUser情報をDumpすることができました。

image.png

このユーザ情報がどこに保管されているかというと、LaravelのSessionになります。
Chromeであれば、Developer ToolsのApplicationタブのCookieの中にある、laravel_sessionがSession Cookieになります。

image.png

Session情報の中身はサーバー内で保管されています。
サンプルアプリケーションでは、SESSION_DRIVER=fileになっているので、コンテナに入って確認してみます。

docker exec -it {container_id} sh
cat storage/framework/sessions/{文字羅列}

中には、トークンとユーザの情報が含まれていました。

  • auth0__access_token
  • auth0__id_token
  • auth0__user

どうやら、Universal Loginでセントラルログインをしたとしてもセッション情報はLaravel側で管理されるようです。

2. React製のSingle Page Application

image.png

Laravel同様QuickStartを利用します。Reactの場合[このQuickStart]を利用します。
設定の流れは大体Laravelと同じなので割愛します。必ずLaravelとは別のAuth0 Applicationを作成してください。

注意点として、複数サービスでのログインしたときの挙動をテストしたいので、PortはLaravelのものとは別にします (適当に5000番とかにしてください)。

React側でPortを変更する場合は、exec.shを以下のように書き換えてください。

#!/usr/bin/env bash
docker build -t auth0-react-01-login .
docker run --init -p 5000:3000 -it -e auth0-react-01-login

ReactのSPA環境が出来上がると、以下のような画面が表示されると思います。

image.png

早速ログインしてみます。Laravelのサンプルで使用したブラウザでログインしてみてください。
すると、以下のような画面が表示されます。
英語ですが、 あなたのprofileとemailにアクセスする許可をアプリケーションに与えても良いか?というふうに問われています。

image.png

お気づきかもしれませんが、このとき別アプリケーションにも関わらず、ログイン画面は表示されませんでした。
この連携の許可だけ行うと、Reactのサンプルアプリケーションの方でもログインされたことになります。
連携の許可後、 http://localhost:5000/profile にアクセスしてみるとユーザ情報を見ることができます。

image.png

さて、このユーザー情報はどこで管理されているのでしょうか?
先程と同じようにCookieを見てみます。

image.png

すると、 auth0.is_authenticated というKeyでログイン状態が管理されていました。
実際にこのCookieを削除したりfalseにしたりしてみましたが、Reactアプリケーション上でのみログアウトされました。

ログアウトの挙動はどうなるか

LaravelとReactの2つのアプリケーションが建てられたところで、片方のアプリケーションでログアウトした場合の挙動がどうなるかを試してみます。

まず、2つのアプリケーションにログインします。
次に、Reactアプリの方でログアウトしてください。
その後、Laravelアプリの画面へ行き、更新ボタンを押してください。

どのような挙動になったでしょうか?

恐らく、Laravelのアプリケーション側ではログアウトされずにログインセッションが保たれたままになっているかと思います。

つまり、Auth0でUniversal LoginでSSOをした場合は、アプリケーション側のセッション情報はアプリケーション側で管理するようになっているということがわかります。

まとめ

Auth0のUniversal LoginでSSOをどのように実現しているのか実験してみました。

結果として、セントラルログインをした場合は、Auth0ドメイン上にSession Cookieが保管され、一度ログインした後は、ログイン画面を見ずともログイン状態になることが確認できました。

しかし、ログアウトした場合はログアウトしたアプリケーションのみログアウトされ、ログアウトしていないアプリケーションのセッションは継続されることがわかりました。
つまり、SSOをしていたとしてもログインセッションはアプリケーション側で管理する必要があるということです。

仮に、一つのアプリケーションでログアウトしたら、他のアプリケーションでもログアウト状態にしたいユースケースでは、認証が必要なページで、大元のAuth0のセッションが切れていないか確認する処理が必要になりそうです。

Auth0はかなりカバーされている範囲も広いし、IDaaSの中では最強クラスだと思っているので、これからどんどん使い倒していくこうと思います。現場からは異常です。

26
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?