プロジェクトに OIDC サーバーを統合するための完全ガイド
OIDC (OpenID Connect) サーバーをプロジェクトに統合するためのベストプラクティスを学び、ステージ上でコンポーネントがどのように相互作用するかを理解します。
集中型の認証および認可システム、いわゆるアイデンティティ アクセス管理 (IAM) またはアイデンティティ プロバイダー (IdP) が必要な状況に直面することがあります。時には顧客 IAM や労働力 IAM など、ビジネスを特定するための言葉が追加されることもあります。
これらの華やかな名前はひとまず置いておきましょう。IAM の必要性は、アプリケーションが成長しているためである場合もあれば、始めからベンダーに困難な作業を委任する予定であるためである場合もあります。どちらにしても、プロジェクトにアイデンティティ システムを導入する時期が来ています。
OAuth 2.0 の人気を考慮すると、OpenID Connect (OIDC) は多くの開発者にとって自然な選択です。OIDC は OAuth 2.0 の上に構築された認証レイヤーであるため、OIDC を扱い始めるときには親しみを感じるかもしれません。それでは始めましょう!
OIDC サーバーとは何か、またなぜ OIDC サーバーを統合する必要があるのか?
OIDC サーバー、またはアイデンティティ プロバイダーは、ユーザーの認証と認可を管理する集中型システムです。マルチアプリ ビジネスのための集中型アイデンティティ システムが必要な理由 で議論したように、集中型のアイデンティティ システムには多くの利点があり ます。
プロジェクトがシンプルなウェブ アプリケーションから始まり、認証が組み込まれているとしましょう。
プロジェクトが成長するにつれて、モバイル版を導入する必要が生じます:
ユーザーが各アプリケーションごとにアカウントを作成しなければならないとしたら、悪い体験になるでしょう。ウェブ アプリケーションで始めたので、モバイル アプリケーションは認証のためにウェブ アプリケーションと通信させます:
この時点で、ユーザーが新しい API サービスを導入しています。有料ユーザー向けのサービスであるため、ユーザーがサービスにアクセスする資格があり、認可されていることを確認する必要があります。これを実現するために、ウェブ アプリケーションを通してサービスをプロキシすることができます:
または、何らかのトークン技術を使用してユーザーを認証し、サービス内のウェブ アプリケーションと通信してトークンを検証することで、モバイル アプリケーションが直接サービスを使用できるようにします:
状況が混沌としてきました。そこで認証と認可のロジックを別サービスに分割することに決めます:
リファクタリングプロセスは苦痛を伴います。プロジェクトにアプリケーションやサービスを追加するにつれて、その複雑さが飛躍的に増加することに気付くかもしれません。さらに悪いことに、パスワードなしログイン、ソーシャルログイン、SAML など、複数の認証方法を維持する必要があるかもしれません。
これが、プロジェクトの拡大を計画しているときに、初めからアイデンティティ プロバイダーを導入した方が良い理由です。
OIDC サーバーを統合するためのベストプラクティス
OIDC プロバイダーを探す
市場には多くの OIDC プロバイダーがいます。要件や好みに応じて選択することができます。プロバイダーが OIDC に準拠している限り、プロジェクト内で同じ役割を果たします。
OIDC での "subject," "client," そして "audience" は何を意味するのか?
概念を簡略化すると、subject は client を介して audience へのアクセスを要求しているエンティティとして考えることができます。
典型的なシナリオを見てみましょう:
1. ユーザーがウェブ アプリケーションでサインイン ボタンをクリックする
従来のサーバーサイド レンダリング ウェブ アプリケーションでは、フロントエンドとバ ックエンドが密接に結合されています。ウェブ アプリケーションがフロントエンドとバックエンドの両方を提供していたとしましょう:
- Subject: ユーザー
- Audience: OIDC サーバー
- Client: ウェブ アプリケーション
audience が OIDC サーバーであることが直感に反するように見えるかもしれません。実際には、これがエンドユーザーに SSO (Single Sign-On) 体験を実現する鍵です。以下に、authorization code flow の簡略化されたシーケンス図を示します:
code
は様々なトークン(アクセストークン、ID トークン、リフレッシュトークンなど)に交換できる一度限りのコードです。これらのトークンすべてを今すぐ理解できなくても大丈夫です。進めていくうちに、より良い理解が得られるでしょう。
上記のケースでは、ユーザーは別のアプリケーションに切り替える際に再度サインインする必要はありません。なぜなら、ユーザー(subject)はすでに OIDC サーバー(audience)で認証されているからです。
2. ユーザーがシングルページ アプリケーションを使用する
シングルページ アプリケーション(またはモバイル アプリケーション)では、フロントエンドとバックエンドが分離されています。バックエンドが API サービスであるとします:
- Subject: ユーザー
- Audience: API サービス
- Client: シングルページ アプリケーション (SPA)
authorization code flow の簡略化されたシーケンス図:
API サービスは非インタラクティブであるため、SPA は API サービスを audience としてアクセストークンを使用する必要があります(トークン内の aud
)。
なぜ OIDC サーバーは依然として audience なのか?
技術的には、audience リストから OIDC サーバーを削除することができます。ほとんどの場合、ユーザー情報が OIDC サーバーから必要になるため(OIDC サーバーが audience であることが必要です)、ユーザーとの対話が含まれる場合は常に OIDC サーバーを audience リストに含めておく方が良いです。
待って、それで、authorization request で複数の audiences を持つことができると言っているの?
そのとおりです!OIDC は OAuth 2.0 の上に構築されており、RFC 8707(OAuth 2.0 のためのリソースインジケーター)を活用して、authorization request で複数の audiences を指定することが可能です。grant と OIDC サーバーの両方がサポートしている必要があります。Logto は、この機能をネイティブにサポートしています。
3. マシン間の通信
サービス A がサービス B を呼び出す必要があるとしましょう:
- Subject: サービス A
- Audience: サービス B
- Client: サービス A
client credentials grant の簡略化されたシーケンス図:
サービス B がサービス A を呼び出す必要がある場合、役割は単に反転します。
まとめ
- Subject: ユーザー、サービス、または audience にアクセスする必要がある任意のエンティティ。
- Client: ウェブ アプリケーション、モバイル アプリケーション、またはリクエストを開始したり、subject の代わりに行動する任意のエンティティ。
- Audience: サービス、API、または subject にアクセスを提供する任意のエンティティ。
アクセストークン、ID トークン、リフレッシュトークンとは何か?
OIDC を使用しているときに遭遇する可能性のある3つのトークンがあります:
- アクセストークン: audience にアクセスするために使用されます。JWT (JavaScript Object Notation Web トークン) または不透明なトークン(通常はランダムな文字列)のいずれかです。
- ID トークン: ユーザー情報を含む OIDC 固有のトークンです。常に JWT 形式です。クライアントはトークンをデコードしてユーザー情報を取得できます。
- リフレッシュトークン: アクセストークンまたは ID トークンが期限切れになったときに、新しいトークンセットを取得するために使用されます。
これらのトークンの詳細な説明は、OIDC プロトコ ルでのリフレッシュトークン、アクセストークン、ID トークンについての理解を参照できます。
上記のシナリオ 1 と 2 では、authorization request という用語は、特定の grant を使用してトークンセットを取得するためのリクエストを指します。
すべてがうまくいくと、「トークンを code
で交換する」ステップでトークンのセットが返されます。セット内の利用可能なトークンは、特に authorization request の scope
パラメーターを含む複数の要因によります。単純化のために、すべてのトークンがセット内に返されると仮定します。アクセストークンの期限が切れると、クライアントはユーザーの操作なしにリフレッシュトークンを使用して新しいトークンセットを取得できます。
シナリオ 3 については、クライアント資格情報グラントはアクセストークンのみを返すため、より簡単です。
OIDC で複数の audiences をどのように処理するか?
クライアントが複数の audiences にアクセスする必要がある場合、1 度に 1 つのアクセストークンしか返されないことに気付くかもしれません。この場合、どのように対処するのでしょうか?
2 つの一般的な解決策があります:
コード交換リクエストで resource
を指定する
クライアントがコードとトークンを交換するときに、リクエストで resource
パラメーターを指定できます。OIDC サーバーは、該当する場合、指定された audience のアクセストークンを返します。
以下は非規範的な例です:
それから、OIDC サーバーは、該当する場合には、API_SERVICE
の audience のためのアクセストークンを返します。
リフレッシュトークンを使用して新しいアクセストークンを取得する
RFC 8707 を使用すると、クライアントはリフレッシュトークンを使用してトークンを更新するときに resource
パラメーターを複数回使用して、複数の audiences を指定することができます。
以下は非規範的な例です:
これは前の解決策と同じ効果を持ちます。同時に、他の許可された audiences は将来のトークンリクエストでも利用可能です。
クライアント資格情報グラント
クライアント資格情報グラントで resource
パラメーターを使用して audience を指定することもできます。このグラントで複数の audiences 問題はありません。なぜなら、単に別のトークンリクエストを送信して異なる audience のための新しいアクセストークンを要求することができるからです。
API サービスを保護する
シナリオ 2 の「API サービス」とシナリオ 3 の「サービス B」には共通点があります。それは、リクエストが認可されているかどうかを判断するためにアクセストークンを検証する必要があることです。アクセストークンの形式によって、検証プロセスは異なる場合があります。
- 不透明なトークン: API サービスは、トークンを検証するために OIDC サーバーに問い合わせる必要があります。この目的のために、イントロスペクション エンドポイント が通常 OIDC サーバーによって提供されています。
- JWT: API サービスは、署名とトークンのクレームをチェックすることで、ローカルにトークンを検証することができます。OIDC サーバーは通常、API サービスが署名を検証するために公開鍵を取得するための JSON Web Key Set (JWKS) エンドポイント (
jwks_uri
) を提供します。
JWT に不慣れな場合は、「JSON Web トークン (JWT) とは何か?」を参照してください。実際、通常、署名を検証したり manually にクレームを確認する必要はありません。なぜなら、Node.js やウェブ ブラウザーのための jose のような多くのライブラリがそれを代わりに行ってくれます。
クレームを確認する
JWT 署名を検証するだけでなく、API サービスはトークン内のクレームを常に確認する必要があります:
iss
: トークンの発行者。OIDC サーバーの発行者 URL と一致する必要があります。aud
: トークンの audience。API サービスの audience 値(通常は有効な URI)と一致する必要があります。exp
: トークンの期限切れ時間。API サービスは期限切れのトークンを拒否する必要があります。scope
: トークンの scope(権限)。API サービスは、トークンに必要な scope が含まれているかどうかを確認する必要があります。
その他のクレーム、例えば sub
(subject)および iat
(発行時間)は、一部のケースで重要です。追加のセキュリティ対策を講じている場合は、対応するクレームを確認してください。
Authorization (認可)
未回答の質問が残っています:どうやって特定の scope(つまり、権限)が subject に付与されるかを判断するのか?
この単一の質問は、Authorization の新しい世界への道を開きますが、この記事の範囲を超えています。簡単に言えば、RBAC(ロールベースのアクセス制御)や ABAC(属性ベースのアクセス制御)などの一般的なアプローチがあります。以下は、これらを始めるためのいくつかのリソースです:
最後の注意事項
プロジェクトに OIDC サーバーを導入することは大きな一歩です。それは、あなたのプロジェクトのセキュリティとスケーラビリティを大幅に向上させることができます。しかし同時に、コンセプトとコンポーネント間の相互作用を理解するのに時間がかかることがあります。
要件や好みに合った優れた OIDC プロバイダーを選択することで、統合プロセスの複雑さを大幅に減らすことができます。プロバイダーは通常、OIDC サーバー、Authorization メカニズム、SDK、将来的に必要になるかもしれないエンタープライズ機能を含む全パッケージを提供しています。
このガイドが OIDC サーバーの統合の基本を理解するのに役立つことを願っています。どれを最初に始めるべきか迷っている場合は、自分たちの Logto、開発者向けのアイデンティティ インフラストラクチャをおすすめしたいと思います。