Auth0でSAML SP/IdPを構築する

# はじめに
この記事はAuth0を使ってSAML Service ProviderとIdentity Providerの環境を構築する手順です。Auth0はSAML SP/IdPのどちらでも機能することが可能で[様々なSAMLのユースケース](https://auth0.com/docs/protocols/saml/saml-configuration)に対応できます。

# 検証環境
- **OS** : `macOS Catalina 10.15.2`
- **node** : `10.15.3`
- **npm** : `6.13.2`

# 手順
## IdP側その1
Auth0のダッシュボードから"Create tenant"を選択して新しいIdP用のテナントを作成します。

<img src="https://i.imgur.com/2Pche6H.png" width=70%>

<img src="https://i.imgur.com/axTWyGj.png" width=70%>

左ペインの"Applications"をクリックして右上の"CREATE APPLICATION"を押します。

<img src="https://i.imgur.com/01vBuOt.png" width=70%>

"Name"に任意の名前を入力して"Choose an application type"で"Regular Web Applications"を選択して"CREATE"を押します。

<img src="https://i.imgur.com/hPMIyRm.png" width=70%>

"Settings"タブの下にある"Show Advanced Settings"をクリック、"Endpoints"タブの"SAML Protocol URL"をクリップボードにコピーします。
**<font color="DarkOrange">このURLをSP側に登録します。</font>**

<img src="https://i.imgur.com/jyFGsih.png" width=70%>

"Certificates"タブをクリックして”DOWNLOAD CERTIFICATE”を押して公開鍵をダウンロードします。
**<font color="DarkOrange">この公開鍵をSP側に登録します。</font>**

<img src="https://i.imgur.com/Z4gmLiF.png" width=70%>

## SP側その1
**<font color="DarkOrange">IdP側その1と同じ手順でIdP用のテナントを作成します。詳細な手順は割愛しています。</font>**

左ペインの"Connections"->"Enteprise"をクリックして"SAML"の"＋"をクリックします。
<img src="https://i.imgur.com/yaFt53f.png" width=70%>

"Connection name"に任意の名前を入力、"Sign In URL", "Sign Out URL"にIdP側その1でクリップボードにコピーしたURLを入力します。"X509 Signing Certificate"にIdP側その1でダウンロードした公開鍵をアップロード、その他の項目は全てデフォルトで下の"SAVE CHANGES"を押します。　
<img src="https://i.imgur.com/yxh6JJf.png" width=70%>

## IdP側その2
作成したApplicationをクリックして”Addons”タブから"SAML2 WEB APP"フリップスイッチをオンにします。

<img src="https://i.imgur.com/CBf118g.png" width=70%>

"Applicai¥tion Callback URL"に`https://SPのテナント名.auth0.com/login/callback?connection=SAMLコネクション名`を入力します。
**<font color="black">例 : `https://pannacotta.auth0.com/login/callback?connection=saml-cookiegaugau`</font>**
"Settings"に"audience": "urn:auth0:SPのテナント名:SAMLコネクション名"を入力して下の"SAVE CHANGES"を押します。
**<font color="black">例 : `"audience": "urn:auth0:pannacotta:saml-cookiegaugau"`</font>**

<img src="https://i.imgur.com/rmbJ20t.png" width=70%>

## Applicationの登録
左ペインの"Applications"をクリックして右上の"CREATE APPLICATION"を押します。

<img src="https://i.imgur.com/ZtGP5PL.png" width=70%>

"Name"に任意の名前を入力、"Choose an application type"で"Simgle Page Web Applications"を選択して”CREATE”を押します。

<img src="https://i.imgur.com/70rHJkw.png" width=70%>

"Settings"タブをクリックして"Allowed Callback URLs", "Allowed Web Origins", "Allowed Logout URLs"に"`http://localhost:3000`"を入力して画面下の"SAVE CHANGES"を押します。
**<font color="DarkOrange">Auth0で認証が成功した際やApplicationからログアウトした際にコールバックできるURLを指定しています。</font>**

<img src="https://i.imgur.com/3To8OCP.png" width=70%>

Applicationの[GitHubリポジトリ](https://github.com/auth0-samples/auth0-react-samples)をローカルPCにクローンします。
**<font color="DarkOrange">Auth0は65以上の言語やフレームワークに対応したSDK、それらのSDKを利用したサンプルアプリケーションをGitHubに公開しています。一から実装する必要は無いのでそれらを検索して利用して下さい。</font>**

```console
$ git clone https://github.com/auth0-samples/auth0-react-samples.git
```

auth0-react-samples/01-Login/srcに移動します。

```console
$ cd auth0-react-samples/01-Login/src
```

auth_config.json.exampleをコピーしてauth_config.jsonを作成します。

```console
$ cp auth_config.json.example auth_config.json
```

auth_copnfig.jsonを編集します。
**<font color="DarkOrange">"clientID"は"Appications"->"作成したApplication"->"Settings"から確認できます。</font>**

```json
{
  "domain": "kiriko.auth0.com",
  "clientId": "xxxx"
}
```

auth0-react-samples/01-Loginに移動します。

```console
$ cd auth0-react-samples/01-Login
```

npm installを実行して必要なパッケージをインストールします。

```console
$ npm install
```

npm startを実行してApplicationを起動します。

```console
$ npm start
```
Chromeで`http://localhost:3000`にアクセスして右上の"Log in"を押します。
**<font color="DarkOrange">手順通りに設定していればAuth0　のUniversal Login画面が表示されます。</font>**

<img src="https://i.imgur.com/igwKmVP.png" width=70%>


## SP側その2
SP側その1で作成したSAML Connectionをクリック、”IdP-initiated SSO”タブをクリックして"Default Application"に登録したApplicationを選択して”SAVE CHANGES”を押します。
**<font color="DarkOrange">SAMLをOIDCに変換してIdP-initiated SSOの中間者攻撃によるリスクを回避しています。</font>**

<img src="https://i.imgur.com/Peu0Ywc.png" width=70%>

## 動作確認
SP側のDashboardからApplicationの登録で作成したApplicationをクリックして"Connections"を選択、作成したSAMLのフリップスイッチをオンにしてその他のConnectionsのフリップスイッチをオフにします。

<img src="https://i.imgur.com/XDnhSCf.png" width=70%>

Chromeで`http://localhost:3000`にアクセスして右上の"Log in"を押します。"Log in at xxxx"ボタンを押してユーザをサインアップします。

<img src="https://i.imgur.com/j7H6NGz.png" width=70%>
<img src="https://i.imgur.com/5woAHkq.png" width=70%>
<img src="https://i.imgur.com/Bw7sY1H.png" width=70%>

SP側のDashboard左ペインの"Users&Roles"->"Users"に作成したSAMLコネクションでサインアップしたユーザが表示されていれば成功です。

<img src="https://i.imgur.com/ZjikiJC.png" width=70%>

# 参考
[SAML認証はどのように機能するか？](https://auth0.com/blog/jp-how-saml-authentication-works/)