Open ID Connect で シングルサインオン (SSO)を行う

皆さん、こんにちは。技術開発グループのn-ozawanです。
白菜が安いです。白菜と言えば鍋ですね。皆さんは何の鍋がお好きですか?私はおでんが好きです。

本題です。
前回、OAuth2.0による権限の委譲を紹介しました。OAuth2.0はリソースの所有者が、クライアントに対して、所有するリソースへのアクセス権限を委譲するための認可の仕組みです。このOAuth2.0をベースに認証を行えるようにしたのがOpen ID Connect (OIDC)という規格です。今日はOIDCについてのお話です。

Open ID Connect (OIDC)

認証と認可

前回、認証とは「アクセスしてきた利用者が本人かどうかを確認すること」であり、認可とは「アプリなども含む利用者にアクセス権限を与えること」です。また、OAuth2.0は「認可」に該当する、とお話ししました。

今回お話しするOIDCは「認証」に該当します。

シングルサインオンとは?

OIDCはシングルサインオンを実現する規格として利用されています。シングルサインオンとは、最初に認証を行いログイン出来れば、その他のシステムに対してもログイン出来るようにする仕組みです。

システム開発ではいくつものシステムを利用しながら開発を進めます。また、システム開発でなくても、会社がその業務を遂行するために複数のシステムを導入するケースもあります。SSOを利用しない場合、それらシステムごとにアカウント登録を行い、システムごとに認証を行います。SSOを利用した場合、一度、認証サーバーで認証を行えば、以降はシステムごとの認証は不要になります。

SSOのメリットはアカウントの管理が1つで済むことにあります。利用者から見れば認証を1回で済ませられるので利便性が上がりますし、複数のパスワードを管理する手間もなくなります。また、アプリサーバーはパスワードという秘匿情報を持つ必要がなくなるため、セキュリティへのコストダウンにもなります。

何故、OAuth2.0は認証に使えないのか?

OAuth2.0では、認可サーバーからリソース所有者へ、クライアントに権限を委譲しても良いか確認します。その際、認可サーバーはリソース所有者が本人であるかを確認します。確認手段は様々ですが、多くはリソース所有者へIDとパスワードの入力を促します。つまり、認可サーバーはリソース所有者へ確認する過程で、認証も行っていることになるため、認可サーバーが発行するアクセストークンを「認証した証明」と解釈することも出来ます。しかし、これは間違った解釈です。

アクセストークンは「認証した証明」にはなりません。その主な理由は以下の通りです。

  • クライアントはアクセストークンの中身を見ることが出来ないため、誰がログインしたのかを判断することが出来ない
    OAuth2.0では、アクセストークンの中身に関する仕様は特に明記されていません。アクセストークンの中身を把握しているのは認可サーバーとリソースサーバーです。クライアントはアクセストークンを発行してもらい使うだけであり、その中身を把握するようなことは想定していません。
  • アクセストークンはリフレッシュトークンなどで、リソース所有者がアクセスしていないにも関わらず、クライアント起因で再発行してもらう仕組みが存在する
    リソース所有者がPCを閉じた後も、クライアントはリフレッシュトークンによる、アクセストークンの再発行を行うことが出来ます。その状態で、アクセストークンを根拠にリソース所有者が「ログインしている状態」というのは難しいものがあります。
  • そもそもOAuth2.0の認可付与方式では、リソース所有者を通さずにアクセストークンを発行する手段がある
    前回の投稿では取り上げませんでしたが、アクセストークンを発行するフローには、クライアント・クレデンシャルによる付与方式があります。これはリソース所有者が存在しないケースで利用される認可付与方式で、クライアント自体がリソース所有者ように振る舞う方式です。

IDトークン

OAuth2.0ではアクセストークンを「認証した証明」として扱うことを想定していません。なので、OIDCでは「認証した証明」としてIDトークンを発行します。以下はIDトークンが発行されるまでの簡単なプロセスになります。

OIDCは認証シーケンスなので、リソースサーバーはいません。OAuth2.0で呼ばれていたクライアントは、OIDCでは「リライング・パーティ(RP)」と呼びます。また、認証を行いIDトークンを発行するサーバーを「アイデンティティ・プロパイダ(IdP)」と呼びます。

ユーザーとIdPとの間で認証が成功すると、IdPはRPへIDトークンを発行します。IDトークンのフォーマットはJWT+JWSと定められており、IDトークンには認証に成功したユーザーの情報が含まれています。そのため、RPはIDトークンから誰がログインしてきたのかを確認することが出来るようになります。

なお、上の図ではIDトークンのみを発行していますが、多くの場合、IdPはOAuth2.0の認可サーバーと同様にアクセストークンも発行します。RPはIDトークン、アクセストークンを受け取ることになります。

認可コードによる認証方式

OIDCも多様なユースケースを想定して、いくつかの認証方式を用意しています。しかし、OAuth2.0をベースにしているため、そのシーケンスはOAuth2.0とほぼ同じです。以下は主に使われる「認可コードによる認証方式」のシーケンスです。

OAuth2.0の「認可コードによる付与方式」と同じですが、違うところはトークンエンドポイントからIDトークンとアクセストークンを取得するところになります。取得したアクセストークンにより、UserInfoエンドポイントからユーザー情報を取得することが出来ますが、これは必須ではありません。先に述べた通り、IDトークンからある程度のユーザー情報を得ることが出来ます。

おわりに

OIDCもOAuth2.0に負けず、多様な認証シーケンスが定義されています。ただ、利用するIdPがそれら多様な認証シーケンスの全てに対応している訳ではありませんので、認証環境を構築する際はIdPのマニュアルを読むことをお勧めします。

ではまた。

Recommendおすすめブログ