Autn0 Learn Identityのポイントその1 - Introduction to Identity

# はじめに
この記事はAuth0が提供している[Lean Identitiy - Introduction to Identity](https://auth0.com/docs/videos/learn-identity/01-introduction-to-identity)のポイントをまとめています。

# 解説
## Identityの何が問題なのか?
ユーザの根本的な欲求は何らかの情報を提供しているリソースにアクセスして欲しい情報を入手することと言えます。ユーザはWebブラウザやモバイルアプリからApplicationにアクセスしてResource Serverにアクセスして欲しい情報にアクセスしますが、<font color="DarkOrange">Applicationも多種多様な種類が存在し、Softwareプログラミングでアクセス制御の仕組みを一から作ることは一筋縄ではいきません。また、ユーザのIDもSocial Providerや企業内のEnterprise Directory等、あらゆるデータソースに置かれていて複雑になっています。</font>

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

## 問題を解決するためにAuth0ができること
Auth0はOpen ID ConnectやOAtuh2のような標準プロトコルで規定されている<font color="DarkOrange">ベストプラクティスが実装済みのSDKやSample Application、詳細な実装手順を掲載したチュートリアル</font>を多く公開しており、Application開発者の皆様がID関連の工数を削減できる環境を取り揃えています。また<font color="DarkOrange">IDが置かれているあらゆるデータソースを抽象化してID管理の複雑性を回避できます。</font>

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

## IDの標準プロトコル
Auth0はOpen ID Connect, OAuth2, JSON Web Token, SAML等、<font color="DarkOrange">業界標準のプロトコルのみサポート</font>しており、B2C, B2B, B2E等あらゆるユースケースに適用することが可能ですまた、Auth0はこれらの標準プロトコルで規定されているベストプラクティスを実装済みで、Application開発者の皆様は実装の詳細を意識することなく、ビジネス機能の実装に集中頂くことができます。

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

## ディレクトリサービスの限界
90年代中盤頃、Windows Active DirectoryやLDAPなど、複数のApplicationで共有できるディレクトリサービスにユーザのクレデンシャルを一元管理する手法が一般化され始めました。ディレクトリサービスは個々のApplication毎に認証ストアを持つ必要が無く管理性も高い反面、<font color="DarkOrange">自社内での利用に限定される限界</font>がありました。

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

## クロスドメインSSO
ディレクトリサービスの限界に対応するために、社外のディレクトリサービスを利用できないか検討が始まりました。当初は、相手側のディレクトリサービスに自社のクレデンシャルのコピーを作る(Shadow Account)動きが見られましたが、一貫性を保ちながら運用し続けるのが困難なことはわかってきました。

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

2006年頃にIBM, Sun Microsystems等、当時の主要企業が協議してディレクトリサービス間の信頼を確率する<font color="DarkOrange">SAML(Security Assertion Markup Language)</font>が誕生しました。SAMLでSP(Service Provider)とIdP(Identity Provider)間の信頼を確率することで、自社内のディレクトリサービスのクレデンシャルで相手側のApplicationにSSOすることが可能になりました。

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

ユーザが正しく認証されたことを証明する<font color="DarkOrange">Security Token</font>が誕生し、認証したプロバイダ、認証されたユーザ、認可されたリソースの情報をパッケージされたSecurity Tokenで管理できるようになりました。

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

更に進んで、SP-IdP間でSecurity Tokenの取り交わしが完了した後に<font color="DarkOrange">Session Cookie</font>を両者間で張ることで、Security Tokenの取り交わしは一回で済むようになりました。

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

## Password共有のアンチパターン
ユーザがLinkedinにログインして、LinkedinからGoogleのAPIをコールするシーンを考えます。LinkedinはGoogleのAPIをコールするために、<font color="DarkOrange">ユーザにGoogleのクレディンシャルを渡して欲しい</font>とお願いします。GoogleのクレディンシャルをもらったLinkeinはこのクレディンシャルを元にGoogleにログインしてGoogleのAPIをコールします。このパターンは、Linkedinが受け取ったGoogleのクレデンシャルを安全性の低いストレージに保管してしまい、<font color="DarkOrange">悪意を持った攻撃者にクレデンシャルを盗まれてしまう懸念</font>があります。更に、GoogleのクレデンシャルはGoogleのAPIに対して何でもできてしまう権限を持っているため、LinkedinはEmailを読んだり・送信したり・削除したり<font color="DarkOrange">やりたい放題です。</font>

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

## 権限移譲型認可 - OAuth2
Password共有の問題を解決するために、Applicationに特定のことだけを認可する仕組みであるOAuth2が誕生し、"認可サーバ"という新しいエンティティが出てきました。以下、Linkedinでのユーザ認証からGoogle APIへのアクセスまでの大まかなフローです。

1. LinkedinでLoginボタンを押す
2. 認可サーバにリダイレクトされてID/Passwordを入力する
3. 認可サーバは入力されたID/Passwordと認証Database上のID/Passwordを照合して、照合に成功したらLinkedinに認可コードを払い出す
4. Linkedinは認可サーバから払い出された認可コードを自分のクレデンシャル(Application ID/Secrect)を認可サーバに渡し、Acccess Tokenの払い出しを依頼する
5. 認可サーバはLinkedinから受け取った認可コードとクレデンシャルを検証して、検証に成功したらLinkedinにTokenを払い出す
6. Linkedinは認可サーバから払い出されたAccess Tokenを利用してGoogle APIにアクセスして必要な情報の提供を依頼する
7. Google APIはLinkedinから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する

Access Tokenにはユーザに認可された処理(例/Emailの閲覧)のみが含まれており、<font color="DarkOrange">必要最低限の処理だけ認可される仕組み</font>になっています。これにより、Password共有のアンチパターンを回避することができます。

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

## Open ID Connect
OAuth2によって必要最低限の処理だけ認可される仕組みはできましたが、Access Tokenには<font color="DarkOrange">"誰が認可されたのか?"</font>の情報が含まれていないため新たな課題が露呈されました。そこで、再度主要企業が中心となり協議がなされ"誰"についてもカバーしたOpen ID Connectが誕生し、Access Tokenと同時に"誰が認可されたのか?"の情報を含む<font color="DarkOrange">ID Token</font>がApplicationに払い出されるようになりました。ApplicaitonはID Tokenを検証して、一度認証されたユーザについては認可サーバに再認証することなく認証済みと見なしたり、ID Tokenに含まれるユーザ属性を取り出して表示したりできるようになりました。

# おわりに
IDのみならず、馴染みのない世界は必要以上に複雑に見えて、習得する際の入り口を探すのに苦労するケースは少ないくないと思います。Auth0が提供している[Lean Identitiy - Introduction to Identity](https://auth0.com/docs/videos/learn-identity/01-introduction-to-identity)は複雑怪奇なIDを可能な限り単純でわかりやすく解説しています。