Spring SecurityやSpring Authorization Serverの主要開発者であるJoe Grandja氏が、OAuthの基礎や実装上の考え方、Spring Authorization Serverの役割について語るポッドキャストが公開されました。OAuthやOpenID Connectは、いまやWebアプリケーションやモバイルアプリ、マイクロサービスを支える重要な標準仕様です。一方で、用語やフローが複雑なため、認証・認可の処理を独自実装してしまい、セキュリティ上の問題を抱えるケースも少なくありません。
OAuthは「ログインの仕組み」ではなく、認可の標準
OAuth 2.0は、ユーザーの認証そのものを定義する仕様ではありません。あるリソースに対して、クライアントがどのような権限を持つかを委譲するための認可フレームワークです。
たとえば、ユーザーがあるWebサービスから別のサービスのAPIを利用するとします。このとき、ユーザーのパスワードをクライアントに渡すのではなく、認可サーバーを介してアクセストークンを発行します。クライアントは、そのトークンを使ってリソースサーバーへアクセスします。
基本的な登場人物は次のとおりです。
- リソースオーナー:保護されたデータの所有者であるユーザー
- クライアント:APIを利用するアプリケーション
- 認可サーバー:アクセストークンを発行するサーバー
- リソースサーバー:APIや保護対象データを提供するサーバー
この役割分担を理解しないまま、「ログインAPI」や「JWTを返すエンドポイント」を独自に作ると、トークンの発行条件、リダイレクト先の検証、失効、スコープ管理などで設計漏れが発生しやすくなります。
OpenID Connectは認証情報を扱うための拡張
OAuthだけでは、アクセストークンを持つ人物が誰なのかを標準的に確認する仕組みまでは定義されません。そこで利用されるのがOpenID Connect(OIDC)です。
OIDCはOAuth 2.0をベースに、IDトークンやUserInfoエンドポイントなどを追加し、ユーザー認証とその情報提供を標準化します。一般的な「ソーシャルログイン」やシングルサインオンでは、OAuthの認可フローとOIDCの認証機能が組み合わせて使われます。
実装時には、アクセストークンとIDトークンを同じものとして扱わないことが重要です。アクセストークンはAPIへのアクセス権を示すものであり、クライアントがユーザー情報を確認するためのトークンとは目的が異なります。トークンの用途を混同すると、意図しないAPIアクセスや情報漏えいにつながる可能性があります。
Spring Authorization Serverが解決する課題
Spring Securityは、アプリケーション側の認証・認可や、保護されたリソースへのアクセス制御を支援するフレームワークです。一方、Spring Authorization Serverは、OAuth 2.0やOpenID Connectに基づく認可サーバーをSpringエコシステム上で構築するためのプロジェクトです。
つまり、Spring Securityが「アプリケーションやAPIを守る側」の機能を中心に提供するのに対し、Spring Authorization Serverは「トークンを発行し、クライアントや認可フローを管理する側」の基盤を提供します。
これにより、開発者は次のような処理を、仕様を意識しながら組み立てられます。
- OAuthクライアントの登録と管理
- 認可コードフローの処理
- アクセストークンやリフレッシュトークンの発行
- クライアント認証
- スコープに基づく権限管理
- OIDCのディスカバリーやIDトークンへの対応
- トークンイントロスペクションや失効に関する機能
ただし、ライブラリを導入すれば自動的に安全になるわけではありません。認可サーバーはアプリケーション全体の信頼の中心となるため、クライアント登録情報、ユーザーデータ、暗号鍵、トークン保存方式などを適切に設計する必要があります。
実運用で確認すべきセキュリティ設計
第一に、認可コードフローではPKCEを利用することが重要です。特にモバイルアプリやSPAなど、クライアントシークレットを安全に保持できない環境では、認可コードの横取りに備える必要があります。現在の構成では、機密クライアントを含めてPKCEを標準的に採用する設計が有力です。
第二に、リダイレクトURIを厳密に管理します。ワイルドカードや過度に柔軟なパターンを許可すると、認可コードやトークンが攻撃者の管理するサイトへ送信される危険があります。登録済みのURIとの完全一致を基本とし、環境ごとの設定も明確に分離すべきです。
第三に、トークンのライフサイクルを設計します。アクセストークンの有効期限を長くしすぎると、漏えい時の被害が拡大します。リフレッシュトークンを使う場合は、ローテーション、失効、再利用検知、保存時の保護まで検討しなければなりません。
さらに、秘密鍵やクライアントシークレットをソースコードや設定ファイルへ直接記述しないこと、TLSを必須にすること、監査ログにトークンや個人情報を出力しないことも基本的な対策です。署名鍵のローテーションや、複数インスタンスで動かす場合の鍵・認可情報の共有方法も、運用開始前に決めておく必要があります。
自前実装のリスクをどう考えるか
認証認可の処理は、単純なログイン機能に見えても、仕様準拠、攻撃への耐性、暗号処理、互換性、将来の拡張を同時に満たす必要があります。独自のトークン形式や独自エンドポイントを作ると、短期的には実装が早く見えても、後からクライアント追加や外部サービス連携が必要になった際に大きな負債になります。
標準仕様に基づく実装を選ぶメリットは、単にセキュリティ機能を再利用できることだけではありません。クライアントやAPIゲートウェイ、監視ツール、他の認証基盤との接続において、共通の前提を持てる点にもあります。
Spring Authorization Serverを採用する場合も、まず要件を整理し、認証を誰が担うのか、どのAPIにどのスコープを付与するのか、トークンをどこで検証するのかを明確にすることが重要です。既存のIDaaSやクラウドの認証サービスで要件を満たせるなら、それらを利用する選択肢も含めて比較すべきでしょう。
Joe Grandja氏の解説から得られる重要な示唆は、OAuthやSpringの機能を覚えることだけではありません。認証と認可をアプリケーション固有の処理から切り離し、標準仕様、明確な責務分担、継続的な運用を前提に設計することです。Spring SecurityとSpring Authorization Serverを適切に組み合わせることで、開発チームは独自実装のリスクを抑えながら、拡張可能な認証認可基盤を構築できます。
出典: Spring

