こんにちは、サイオステクノロジー技術部 武井(Twitter:@noriyukitakei)です。今回は、OpenID Connectをなるべくわかりやすく書きたいと思います。OAuthと同様、このOpenID Connectもなかなかに難解なプロトコルです。そんなOpenID Connectをご理解頂くためのきっかけになれればと思います。
※ OpenID ConnectのベースとなるOAuthの記事も合わせて参考にして頂ければ幸いです。
※ その他OpenID Connectの記事の一覧は以下のリンクをクリックすればご覧になれます。
OpenID Connectとは?
OpenID Connectは、OAuthのフローをベースにしており、本来、クライアント側で行っていた認証処理を、他のサーバー(OpenID Provider)にお任せして、その認証結果のみを安全な方式(JSON Web Token)でクライアントが受け取って認証する方式です。
よくある説明なのですが、おそらくこれだけではイメージが湧かないと思います。そこで、OpenID Connectがない世界ではどのように認証を行ってどのような不都合が生じていたのか、そしてOpenID Connectがある世界では、それらの不都合がどのように解決されるかを説明することで、OpenID Connectをご理解いただけたらなと思っております。
登場人物
今回の説明の中に登場する人物及びサービスです。
OpenID Connectがない世界
OpenID Connectがない世界で行っている認証を説明します。
まず、Aさんはストレージサービスを利用するために、ストレージサービスにログインします。ID・パスワードを入力すると、ストレージサービスは、ID・パスワード認証処理とデータベースが連携して、AさんIDとパスワードをチェックして、問題なければ認証OKとします。
そこで、ユーザーの要望により、新たにワンタイムパスワード処理を追加することになったとします。ストレージサービスの開発者は夜なべをして、せっせとワンタイムパスワード処理を実装しなければなりません。大変です。
OpenID Connectがある世界
OpenID Connectがある世界ではどうでしょうか?概ね以下のようになっているのではないかと思います。
OpenID Connectでは、今までストレージサービスで行っていたユーザー認証をGoogle側(OpenID Provider)で行います。ここで既にお気づきかと思いますが、今までストレージサービス側にあった「ID・パスワード認証処理」「ワンタイムパスワード認証処理」が、Google側に移動しています。Aさんは、GoogleにID・パスワード・ワンタイムパスワードを入力します。
Googleでの認証が成功すると、認証チケット引換券が渡されます。認証チケット引換券は、Aさんを経由してストレージサービスに渡されます。さらにストレージサービスはその認証チケット引換券をGoogleに渡します。
Googleは認証チケット引換券をチェックして、問題がなければ、ストレージサービスに認証チケットを発行して、認証OKとします。
「OpenID Connectのない世界」と「OpenID Connectのある世界」を比較してみますと、決定的に違うのは、以下の2つが、ストレージサービスからGoogleに移ったことです。
- ID・パスワード認証、ワンタイムパスワード認証などの認証処理
- ユーザーID、パスワードなどの認証情報
上記の2つを実装したり管理したりするのは非常に大変です。ユーザーIDやパスワードは漏洩したら大事件ですし、認証処理だって実装するのは苦労します。通常のID・パスワード認証処理だけならともかく、ワンタイムパスワードなんて言ったら、実装はもっともっと大変です。そんなのは、できればどこかにお願いしたいです。
「OpenID Connectのある世界」では、そんな面倒なことはGoogleに任せています。Googleは世界的に有名な大企業ですので、ユーザーID・パスワードも厳重に管理していますし、認証処理も色々な機能を持っています。そんなGoogleに、先に説明した認証処理やID・パスワード管理をお任せしてしまえば、安心ですし、運用上の手間も軽減することが出来ます。
つまり、OpenID Connectとは一言で言ってしまえば、メンドくさいID・パスワードの管理や認証処理を他にお任せして、楽するためのプロトコルです。
認証の具体的な流れ
では、OpenID Connectの認証の流れを、もうちょっとだけ具体的に説明しています。この説明では、イメージを湧いて頂くために、詳細な処理(例えばstateパラメーターの検証など)を省いておりますが、そこはあくまで意図的にそうしておりますので、何卒ご容赦くださいませm(_ _)m
まず、ストレージサービスのシステム管理者は、Googleに対して、OpenID Connectを行う申請、つまりストレージサービスの認証をGoogle側に委譲するための申請を行います。これは具体的には、クライアントIDとクライアントシークレットを発行してもらう作業です。このクライアントIDはOpenID Connectを利用するサービスを一意に識別するIDであり、今回の場合はストレージサービスのための固有なIDを発行してもらいます。クライアントシークレットは、クライントIDのパスワードになります。これら2つは、誰にも漏らすことなく、大切にストレージサービス側に保存をします。
ストレージサービスのシステム管理者は、先程Googleから発行されたクライントIDとクライアントシークレットをストレージサービスのデータベースに保存します。ここまでで、ストレージサービスのシステム管理者の仕事は終わりです。次からは、いよいよユーザーの利用になります。
ストレージサービスの利用者であるAさんは、Googleの認証画面にアクセスします。このとき、URLのクエリパラメーターに以下のものを渡します。(本当はもっといろいろありますが、説明を簡略化するために重要なものだけに絞っております)
client_id | クライアントIDを指定します。 |
response_type | 認証チケット引換券(以降、認可コードと呼びます)を取得するためには、このクエリパラメーターにcodeと指定します。 |
Google側の認証画面が表示されるので、ID・パスワード、ワンタイムパスワード等必要な認証情報を入力します。
認証が完了すると、ストレージサービスにリダイレクトされます。このときリダイレクト先のクエリパラメーターに認可コードが付与されます。それと同時にGoogleは、発行した認可コードを自身のデータベースにその有効期限と共に保存します。この有効期限を過ぎた認可コードは無効となります。
認可コードを受け取ったストレージサービスは、認証チケット(以降、IDトークンと呼びます)をGoogleにリクエストします。そのため、Googleに対して、Postメソッド、x-www-form-urlencodedのContent-Typeで以下のパラメーターをリクエストします。(本当はもっといろいろありますが、説明を簡略化するために重要なものだけに絞っております)
code | 認可コードを指定します。 |
client_id | Googleから発行されたクライアントIDを指定します。 |
client_secret | Googleから発行されたクライアントシークレットを指定します。 |
Googleは、ストレージサービスから渡された認可コードをチェックして、その認可コードが存在して、かつ有効期限内だったら、ストレージサービスにIDトークンを返します。IDトークンはJSON Web Tokenの形式になります(JSON Web Tokenの詳細は、「JSON Web Tokenによる認証」を御覧ください)。このIDトークンを検証し、問題なければ、認証OKとします。その検証方法は次に記載します。
IDトークンの検証方法は上記の図のとおりとなります。
(1) ヘッダーとペイロードをピリオドで結合をします。
(2) (1)の値をSHA-256でハッシュ化します。この時のハッシュ化の方法はIDトークンのヘッダー部の「alg」のフィールドに記載してあります。「alg」は署名の方法を記載したフィールドで「RSA256」はSHA-256でハッシュ化したものをRSA暗号化方式で暗号化したものを署名とするという意味になります。
(3) (2)で説明したRSA暗号化方式で必要な公開鍵をGoogleからダウンロードします。この公開鍵は1日1回変更されるので、IDトークンの検証処理を行う際は、その都度、Googleからダウンロードする必要があります。
(4) (3)で取得した公開鍵で署名を復号化します。
(5) (2)でハッシュ化した値と、(3)で復号化した値が同じものであれば、IDトークンはGoogleから発行されたものであることがわかるので、認証OKとします。
最後に
いかがでしたでしょうか?なかなかに複雑なOpenID Connectですが、この記事が皆様の理解の手助けになれば幸いです。
※ OpenID ConnectのベースとなるOAuthの記事も合わせて参考にして頂ければ幸いです。
※ その他OpenID Connectの記事の一覧は以下のリンクをクリックすればご覧になれます。
[…] 多分わかりやすいOpenID Connect – SIOS Tech. Lab […]