概要
色んな種類がありますが、各手法の流れ、メリット・デメリットを整理するためにまとめました。
今回比較するのは以下の4つです。
シーケンス図ではわかりやすさのため以下のようにしています。
名称 | 説明 | 今回の例 |
---|---|---|
UserAgent | ユーザ | User |
Relying Party | サービス提供者 | Server |
Identity Provider | SSO用APIの提供者 |
またRelying Party
は
- Confidential Client:サーバあり。
- Public Client:スマホやJSアプリ。サーバなし。
がありますが、今回は前者を前提としています。
OpenID
最初に簡単な認証方法として出てきたのがOpenIDです。
シーケンス図
メリット
署名の検証作業があるのでセキュリティ上問題無いですし、Googleにサービスの登録作業とかもないので簡単にSSOを導入できます。
デメリット
普及する前に上位互換?であるOAuthが普及してしまったので普及しませんでした。Googleさんも2015/04に廃止予定です。
OAuth2.0を用いた認証(Authorization Flow)
リソースサーバの各API柔軟に利用できるよう作られたのがOAuthです。OAuthとはつまり認可プロトコルです。
そのうちのユーザ情報を取得するAPIを利用して認証に使われるようになりました。
スマホサービスの台頭により一気に普及した感じがあります。
シーケンス図
メリット
サーバ経由ならclientSecret
が漏れないのでセキュリティ上問題ない認証を実装できます。
ポイントはcode
がそのServerのサービス用に発行されたものであるかどうか、clientID
、clientSecret
を使ってちゃんと検証している点です。
なのでcode
をすり替えられても検証時に怒られるので問題がありません。
ただしCSRF攻撃の可能性はあるのでstate
の検証はした方がいいです。
stateがないケース、あるケースの違いは↓が分かりやすいです。
OAuthやOpenID Connectで使われるstateパラメーターについて | SIOS Tech. Lab
デメリット
IdPに登録作業が必要な点くらいでしょうか。
※HTTPSでもcodeが漏れるケースがあり、その場合はcode置換攻撃が可能になるようです
HTTPS でも Full URL が漏れる?OAuth の code も漏れるんじゃね?? - OAuth.jp
OAuth2.0を用いた認証(Implicit Flow)
元々クライアント(スマホ側)だけでサクッと認証ができたらということで使われるようになった手法です。
ただし当然ながら色々な処理を省いたためにセキュリティ上問題が多いです。
今回のようなサーバ経由のConfidential Client
でもこの認証だと抜け道があるので使用すべきでないです。
シーケンス図
メリット
Authorization Flowより簡単に実装できそう(理解していないから)
デメリット
ユーザのところでAccessTokenを別ユーザ用にすり替えられるとそのユーザでログインできちゃいます。
このAccessTokenは別のサービスのものでもOKなんです。だってGoogle側は単にユーザ情報を取得するAPIを提供しているだけなので、そのAPIに「どこどこのサイトのAccessTokenかどうかチェックする」なんて機能はありません。
なので悪意ある人が悪意あるサービスBを提供していると、そのサービスBのAccessTokenを使ってサービスAでなりすましログインできます。
OpenIDConnect
元々OAuthにログイン認証機能なんてなくて、上記の2つはサービス提供側(Server
)が外部API(Google
)から受け取ったユーザ情報を元に勝手にログイン認証を実装してしまったのが問題でした。
なのでちゃんとOAuthで認証できるようにと作られたのがOpenIDConnectです。
認証用なので先程のImplicit Flow
の流れでもセキュリティ上問題なく実装できます(ちゃんと実装すれば)。
シーケンス図
メリット
署名の検証をするので入れ替え攻撃にも対応できセキュリティ上問題無いです。
ユーザの特定にはAccessToken
は用いず、ID Token
の中のユニークIDを使用します。
デメリット
IdPによっては署名の検証機能を提供してないので自前で検証することになります。