はじめに
この記事はAuth0が提供しているLean Identitiy - Introduction to Identityのポイントをまとめています。
解説
Identityの何が問題なのか?
ユーザの根本的な欲求は何らかの情報を提供しているリソースにアクセスして欲しい情報を入手することと言えます。ユーザはWebブラウザやモバイルアプリからApplicationにアクセスしてResource Serverにアクセスして欲しい情報にアクセスしますが、Applicationも多種多様な種類が存在し、Softwareプログラミングでアクセス制御の仕組みを一から作ることは一筋縄ではいきません。また、ユーザのIDもSocial Providerや企業内のEnterprise Directory等、あらゆるデータソースに置かれていて複雑になっています。
問題を解決するためにAuth0ができること
Auth0はOpen ID ConnectやOAtuh2のような標準プロトコルで規定されているベストプラクティスが実装済みのSDKやSample Application、詳細な実装手順を掲載したチュートリアルを多く公開しており、Application開発者の皆様がID関連の工数を削減できる環境を取り揃えています。またIDが置かれているあらゆるデータソースを抽象化してID管理の複雑性を回避できます。
IDの標準プロトコル
Auth0はOpen ID Connect, OAuth2, JSON Web Token, SAML等、業界標準のプロトコルのみサポートしており、B2C, B2B, B2E等あらゆるユースケースに適用することが可能ですまた、Auth0はこれらの標準プロトコルで規定されているベストプラクティスを実装済みで、Application開発者の皆様は実装の詳細を意識することなく、ビジネス機能の実装に集中頂くことができます。
ディレクトリサービスの限界
90年代中盤頃、Windows Active DirectoryやLDAPなど、複数のApplicationで共有できるディレクトリサービスにユーザのクレデンシャルを一元管理する手法が一般化され始めました。ディレクトリサービスは個々のApplication毎に認証ストアを持つ必要が無く管理性も高い反面、自社内での利用に限定される限界がありました。
クロスドメインSSO
ディレクトリサービスの限界に対応するために、社外のディレクトリサービスを利用できないか検討が始まりました。当初は、相手側のディレクトリサービスに自社のクレデンシャルのコピーを作る(Shadow Account)動きが見られましたが、一貫性を保ちながら運用し続けるのが困難なことはわかってきました。
2006年頃にIBM, Sun Microsystems等、当時の主要企業が協議してディレクトリサービス間の信頼を確率するSAML(Security Assertion Markup Language)が誕生しました。SAMLでSP(Service Provider)とIdP(Identity Provider)間の信頼を確率することで、自社内のディレクトリサービスのクレデンシャルで相手側のApplicationにSSOすることが可能になりました。
ユーザが正しく認証されたことを証明するSecurity Tokenが誕生し、認証したプロバイダ、認証されたユーザ、認可されたリソースの情報をパッケージされたSecurity Tokenで管理できるようになりました。
更に進んで、SP-IdP間でSecurity Tokenの取り交わしが完了した後にSession Cookieを両者間で張ることで、Security Tokenの取り交わしは一回で済むようになりました。
Password共有のアンチパターン
ユーザがLinkedinにログインして、LinkedinからGoogleのAPIをコールするシーンを考えます。LinkedinはGoogleのAPIをコールするために、ユーザにGoogleのクレディンシャルを渡して欲しいとお願いします。GoogleのクレディンシャルをもらったLinkeinはこのクレディンシャルを元にGoogleにログインしてGoogleのAPIをコールします。このパターンは、Linkedinが受け取ったGoogleのクレデンシャルを安全性の低いストレージに保管してしまい、悪意を持った攻撃者にクレデンシャルを盗まれてしまう懸念があります。更に、GoogleのクレデンシャルはGoogleのAPIに対して何でもできてしまう権限を持っているため、LinkedinはEmailを読んだり・送信したり・削除したりやりたい放題です。
権限移譲型認可 - OAuth2
Password共有の問題を解決するために、Applicationに特定のことだけを認可する仕組みであるOAuth2が誕生し、"認可サーバ"という新しいエンティティが出てきました。以下、Linkedinでのユーザ認証からGoogle APIへのアクセスまでの大まかなフローです。
- LinkedinでLoginボタンを押す
- 認可サーバにリダイレクトされてID/Passwordを入力する
- 認可サーバは入力されたID/Passwordと認証Database上のID/Passwordを照合して、照合に成功したらLinkedinに認可コードを払い出す
- Linkedinは認可サーバから払い出された認可コードを自分のクレデンシャル(Application ID/Secrect)を認可サーバに渡し、Acccess Tokenの払い出しを依頼する
- 認可サーバはLinkedinから受け取った認可コードとクレデンシャルを検証して、検証に成功したらLinkedinにTokenを払い出す
- Linkedinは認可サーバから払い出されたAccess Tokenを利用してGoogle APIにアクセスして必要な情報の提供を依頼する
- Google APIはLinkedinから提示されたAccess Tokenを検証して、検証に成功したら要求されている情報を提供する
Access Tokenにはユーザに認可された処理(例/Emailの閲覧)のみが含まれており、必要最低限の処理だけ認可される仕組みになっています。これにより、Password共有のアンチパターンを回避することができます。
Open ID Connect
OAuth2によって必要最低限の処理だけ認可される仕組みはできましたが、Access Tokenには"誰が認可されたのか?"の情報が含まれていないため新たな課題が露呈されました。そこで、再度主要企業が中心となり協議がなされ"誰"についてもカバーしたOpen ID Connectが誕生し、Access Tokenと同時に"誰が認可されたのか?"の情報を含むID TokenがApplicationに払い出されるようになりました。ApplicaitonはID Tokenを検証して、一度認証されたユーザについては認可サーバに再認証することなく認証済みと見なしたり、ID Tokenに含まれるユーザ属性を取り出して表示したりできるようになりました。
おわりに
IDのみならず、馴染みのない世界は必要以上に複雑に見えて、習得する際の入り口を探すのに苦労するケースは少ないくないと思います。Auth0が提供しているLean Identitiy - Introduction to Identityは複雑怪奇なIDを可能な限り単純でわかりやすく解説しています。