不透明トークンとJWTの比較
不透明トークンとJWTの違い、それぞれの使用例、およびOIDCベースのシステムでどのように検証されるかを理解します。
Logtoは、OIDCに基づく包括的なCIAMプラットフォームとして、ユーザーとのやり取りを保護し、リソースへのアクセスを管理する上で、認可トークンが重要な役割を果たしています。認可に使用されるさまざまなタイプのトークンの中で、不透明トークンとJWT (JSON Webトークン) が最も重要です。
コミュニティからいくつか質問が寄せられています。たとえば、不透明トークンとJWTの違いは何ですか?受け取ったアクセストークンをデコードできないのはなぜですか?トークンの長さが短く感じるのはなぜですか?このブログ投稿は、これらの概念を明確にし、不透明トークンとJWTの違い、それぞれの使用例、およびそれらを扱う際に異なる動作に遭遇する理由を理解するための手助けをすることを目的としています。
不透明トークンとは何ですか?
不透明トークンは、名前が示すようにクライアントまたは外部の第三者にとって不透明、つまり非表示のアクセストークンの一種です。つまり、トークン自体にはユーザーや付与された認可に関する読み取り可能な情報が含まれていません。
不透明トークンを受け取ると、それはしばしばランダムな文字列のように見え、デコードしようとしても意味のあるデータは得られません。
以下は不透明トークンの例です:
トークンの実際の内容はそれを発行した認可サーバーにのみ知られているため、不透明トークンを検証するには、クライアントはトークンをサーバーに送り返し、サーバーがその信頼性を確認し関連する権限を決定します。このアプローチは、センシティブな情報を隠し、追加のセキュリティレイヤーを提供しますが、トークンを検証するための追加のサーバー通信が必要となります。
長所:
- セキュリティ: 不透明トークンはクライアントに対してセンシティブな情報を公開しません。トークンの内容は認可サーバーにのみ知られています。
- 取り消し可能: トークンはサーバーに保存され、検証方法が認可サーバーのイントロスペクションエンドポイントを通じて行われるため、サーバーは必要に応じて簡単にトークンを取り消し、不正アクセスを防ぐことができます。
- 小さいサイズ: 不透明トークンは通常、JWTより短いため、パフォーマンスやストレージの考慮に有益です。
短所:
- 状態保持: 不透明トークンにはトークンを検証するために認可サーバーが状態を保持する必要があるため、追加の複雑さとオーバーヘッドをもたらす可能性があります。
- パフォーマンス: トークンを検証するための追加のサーバー通信の必要性は、特にトラフィックが多いシナリオでパフォーマンスに影響を与える可能性があります。
JWTとは何ですか?
不透明トークンとは対照的に、JWT (JSON Web Token) は構造化され読み取り可能な形式で情報を含む自己完結型のステートレスなトークンです。
JWTは3つの部分に分かれています: header
、payload
、そしてsignature
、それぞれはBase64URLでエンコードされています。
以下はJWTの例です:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
header
は、トークンのタイプと署名に使用されるアルゴリズムに関する情報を含んでいます。例:{"alg": "HS256", "typ": "JWT"}
。payload
セクションには、ユーザーまたは認可に関する情報(クレーム)が含まれています。例えば、ユーザーID、有効期限、スコープなどです。このデータはエンコードされていますが暗号化されていないため、トークンを持っている誰もがクレームを見ることができますが、署名を無効にしない限り、その内容を変更することはできません。仕様と認可サーバーの設定に基づいて、さまざまなクレームをペイロードに含めることができます。これがトークンの自己完結型の性質をもたらします。例えば、{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
。signature
は、指定されたアルゴリズムを使用してヘッダー、ペイロード、および秘密鍵を組み合わせて生成されます。この署名はトークンの完全性を検証し、不正な変更が加えられていないことを確認するために使用されます。
JWTは、クライアントまたはどのサービスも認可サーバーとやり取りすることなく、ローカルで検証できるため、特に効率的です。この利便性は、複数のサービスが独立してトークン の認証を検証する必要がある分散システムで特に重要です。
ただし、この利便性には、トークンのクレームが誰にでも見られるため、過度に露出されないようにする責任も伴います。また、JWTは通常短命であり、トークンのクレーム内に有効期限が含まれているため、トークンが期限切れまで有効であることを保証します。
長所:
- ステートレス: JWTは自己完結型で、サーバー側のステートが不要です。
- クロスサービスの互換性: JWTは異なるサービス間で簡単に共有され、検証可能なため、分散システムに理想的です。
- 拡張性: JWTのペイロードにはカスタムクレームを含めることができ、柔軟な認可および情報共有を可能にします。
- 標準: JWTトークンは、よく定義された標準 (RFC 7519) に従っているため、広くサポートされ、相互運用性があります。
短所:
- 露出: JWTのクレームはトークンを持つ誰にでも見えるため、センシティブな情報はペイロードに含めるべきではありません。
- 大きなサイズ: JWTは、含まれる追加情報のため不透明トークンより大きくなる可能性があり、パフォーマンスやストレージの考慮事項に影響を与えます。JWTトークンのクレームは最小限に抑えてトークンサイズを小さくする必要があります。
- 取り消しの複雑さ: JWTはステートレスであるため、通常短期間有効であり、期限切れ前にトークンを取り消すための内蔵メカニズムがありません。そのため、トークンが侵害されても、期限切れまで有効である可能性があります。
不透明アクセストークンの検証
不透明アクセストークンは、認可サーバーに送り返して検証されます。認可サーバーは発行されたトークンの状態を維持し、内部ストレージに基づいてトークンの有効性を判断できます。
- クライアントは認可サーバーからアクセストークンを要求します。
- 認可サーバーが不透明トークンを発行します。
- クライアントが不透明トークンをヘッダーに含めてリソースアクセスリクエストを送信します。
- リソースプロバイダーがトークンイントロスペクションリクエストを認可サーバーに送り、トークンを検証します。
- 認可サーバーがトークン情報で応答します。
JWTアクセストークンの検証 (オフライン)
JWTアクセストークンは、トークンの公開鍵にアクセスできるクライアントまたはサービスによってオフラインで検証できます。
- リソースプロバイダーがOIDCディスカバリーエンドポイントから認可サーバーの公開鍵を事前に取得します。公開鍵はトークンの署名を検証し、その完全性を保証するために使用されます。
- クライアントが認可サーバーからアクセストークンを要求します。
- 認可サーバーがJWTトークンを発行します。
- クライアントがJWTトークンをヘッダーに含めてリソースアクセスリクエストを送信します。
- リソースプロバイダーが認可サーバーから取得した公開鍵を使用してJWTトークンをデコードおよび検証します。
- リソースプロバイダーは、トークンの有効性に基づいてアクセスを許可します。
OIDCでの使用例
OIDC (OpenID Connect) のコンテキストでは、不透明トークンとJWTは異なる目的のために使われ、異なるシナリオで使用されます。
不透明トークン
- ユーザープロファイルの取得:
デフォルトで、クライアントがリソースを指定せずにアクセストークンを要求し、openid
スコープを含む場合、認可サーバーは不透明なアクセストークンを発行します。このトークンは主にOIDC /oidc/userinfo
エンドポイントからのユーザープロファイル情報を取得するために使用されます。不透明なアクセストークンを含むリクエストを受け取ると、認可サーバーは内部ストレージを確認して関連する認可情報を取得し、トークンの有効性を確認してからユーザープロファイルの詳細を返します。
- リフレッシュトークンの交換:
リフレッシュトークンは、クライアントと認可サーバーの間だけで交換されることを目的としており、リソースプロバイダーと共有される必要はありません。したがって、リフレッシュトークンは通常、不透明トークンとして発行されます。現在のアクセストークンが期限切れになると、クライアントは不透明なリフレッシュトークンを使用して新しいアクセストークンを取得し、ユーザーを再認証することなく継続的にアクセスを確保できます。
JWTs
- IDトークン:
OIDCでは、IDトークンはユーザー情報を含むJWTであり、ユーザーを認証するために使用されます。通常、アクセストークンとともに発行され、IDトークンはクライアントがユーザーのアイデンティティを検証することを可能にします。例えば:
クライアントはIDトークンを検証してユーザーのアイデンティティを確認し、パーソナライズや認証目的でユーザー情報を抽出できます。IDトークンは一度きりの使用に限られ、APIリソースの認証には使用すべきではありません。
- APIリソースアクセス:
クライアントが特定のリソースインジケーターを指定してアクセストークンを要求すると、認可サーバーはそのリソースをアクセスするためのJWTアクセストークンを発行します。JWTには、リソースプロバイダーがクライアントのアクセスを認証するために使用できるクレームが含まれています。例えば:
リソースプロバイダーはクレームを確認してリクエストを検証できます:
iss
: トークンが信頼された認可サーバーによって発行されたことを確認します。sub
: トークンに関連付けられたユーザーを識別します。aud
: トークンが特定のリソースを対象としていることを確認します。scope
: ユーザーに付与された権限を確認します。
結論
まとめると、不透明トークンとJWTはOIDCベースのシステムで異なる目的を果たし、不透明トークンはセキュアでステートフルな認可のアプローチを提供し、JWTは自己完結型でステートレスな代替手段を提供します。これらのトークンタイプの違いと、それぞれのユースケースを理解することは、アプリケーションにおいてセキュアで効率的な認証および認可メカニズムを設計するために不可欠です。
Logtoのさらなるアクセストークン機能を探る: