【第12回】Amazon Cognito + Spring Sercurityを使ったOAuth2 Loginの実装(1)

現状の実装状況と目指すかたち


前回までに、以下の図のようなバックエンドに配置したマイクロサービスとフロントエンドに配置したWebアプリケーションを想定して実装してきました。


../_images/service-architecture.png


フロントエンドのWebアプリケーションはバックエンドにあるユーザサービスにより取得した認証情報(IDとパスワード)により保護し、 AWS X-Rayを使ってそれらの呼び出し関係を可視化する実装を解説してきました。しかし、認証方式はSpring Securityの理解を深めるもので、 これまで解説してきた、最終的に目指していたアーキテクチャのかたちではありません。また、前回までの実装の説明では、以下のようにローカル環境で構築したアプリケーションの実装例しか示していませんでした。


../_images/current-environment.png


途中経過ではありますが、現在の実装の状況と、最終的に目指すかたちを改めて整理してみましょう。 まず、現状のアプリケーションの実装状況は上のイメージ通りですが、X-RayやDynamoDBといったリージョンサービスをローカル環境から利用しています。 いくつかのサービスはCloudFormationで構築し、CloudFormationスタックからサービスエンドポイントなどの情報をローカル環境からも参照して、ローカル環境から各サービスにアクセスしています。 バックエンドマイクロサービスのアクセスするデータベースは現状HSQLを使ったインメモリデータベースで代替していますが、 次節以降解説していくCognitoとSpring Securityを使ったOAuth2 Loginとバックエンドマイクロサービスをアクセストークンで保護する実装が完了すれば、 AWS環境へ移行する手順を解説する予定です。というのも、次節以降の解説や設定内容は、複雑で間違いやすいので、極力ローカルの統合開発環境などを使ってデバッグしやすい環境を整えて進めていく方がよいでしょう。

次回以降もローカル環境での実装が続きますが、下記のようなAWS環境にあるアーキテクチャ想定のイメージになります。


../_images/next-step-environment.png


次節以降のOAuth2 Loginの解説のために、いったん最終的に構築するアーキテクチャイメージを切り取った、上記の図のスコープで解説を進めます。なお、第2回でも解した通り、最終的には以下のようになります。 クラウドネイティブ・マイクロサービスなアーキテクチャでは段階的にクラウド環境と組み合わせてアプリケーション環境を構築していく手法も取りやすいので、小さな開発スコープで進めていくのが良い方法です。

../_images/microservice-oauth.png



OAuth2 Loginとは何か?


OAuth2 Loginを本連載では、「OAuth2/OpenIDConnect(OIDC)で規定されたプロトコル(OIDCはOAuth2を拡張して認証まで広げたプロトコル)を用いて、アプリケーションへログインさせる仕組み」と定義します。これは、 第2回 でも解説した、認可コードグラントフローによるIDトークンや、アクセストークンを取得するフローそのものを指しています。 一言で説明すると、最近の様々なウェブサイトでよく見かける「XXXX(GoogleやFacebookアカウント等)でログイン」が分かりやすいですが、 ソーシャルログインやOAuth認証など、いくつか類似する紛らわしい語があり、明確に区別しておきます。


用語 説明・OAuth2 Loginとの違い
ソーシャルログイン Google、Facebook、TwitterやLINEをはじめとしたSNSが保持するID/パスワード等を用いて認証を行い、それによって払い出されたトークンを用いて、別のアプリケーションへのアクセスを許可する仕組み。 OAuth2 Loginにはソーシャルメディアのみではなく、Amazon/AWSやApple、GitHubなどに加え、商用サービスとして提供されるOIDCプロバイダや、自前で構築したOIDC準拠のOSSサーバなども含んだ意味で利用する。
OAuth認証 通常、OAuthは認可のためのプロトコルであって、認証(そのユーザを正当なものとして認める処理)とは異なる。OAuth2 Loginでは、あくまで正当に正しく認証されたことを前提として取得されたトークンを使用して、 ログイン処理を代替するものであって、OAuth2プロトコル(アクセストークン)を使って認証するものではない。OAuth認証は、インプリシットフロー等認可コードグラン都フロー以外のものを利用した中で不適切な実装を行うと、 他のサーバで利用されるアクセストークンを流出させる可能性を高めてしまうため、基本的には、OIDCプロトコルに基づいて、IDトークンおよびアクセストークンを取得する必要がある。 なお、払い出されるアクセストークンは合鍵のようなものであり、例えば、その合鍵をもってAPIアクセスしたリクエストが必ずしもそれを利用可能な正当なユーザとは限らない可能性に注意すること (アクセストークンを正当に取得したユーザであっても全てのユーザが、そのアクセストークンだけで保護されたAPIを実行できてしまう)。 一方、OIDCにより払い出されるIDトークンは偽造不可能な名前付きの合鍵であり、サービス利用の権限をより細かく絞ることが可能である。


さて、第2回 で、以下の図における認可コードグラントを用いたフローで解説した通り、このOAuth2 Loginを使用して、OIDCプロバイダ(認可サーバ)からトークンを取得し、 フロントエンドアプリケーションへのログインや、マイクロサービスへのアクセス制御に利用するというのが、本連載で実現する認証認可方式のアイデアでした。


../_images/granted-code-flow.png


このOAuth2 Loginのフローを前節で示した想定のアーキテクチャ図にあてはめると以下のようになります。簡単化のために矢印をいくつか省略していますが、上記のフロー図の中で対応する番号は合わせています。


../_images/oauth2-login-flow.png


なお、第2回で記載した認可コードグラントのフローには事前に記載できなかったものがあり、それはバックエンドのマイクロサービスからCognitoへ出ている「(0)トークンデコードのための公開鍵を取得」になります。 これは、事前にマイクロサービスが送信されてきたトークンを、復号化するためのキーを発行元の認可サーバから取得しておくことで、 マイクロサービスのスケーラビリティを高めるための一助となるものです。もちろん、要件によっては、リクエスト送信時点のトークンの有効性を確認するために 認可サーバ等へ問い合わせを行う必要があるケースもありますが、少なくとも送信されてきたトークンはJWT(JSON Web Token)形式で生成されるため、発行時点の有効性や偽造の有無などは 公開鍵の復号可否によってある程度担保されるため、マイクロサービスを保護するための選択肢の有力なオプションのひとつとして考えると良いでしょう。 なお、JWTトークンの検証について AWS公式Q&Aの「Amazon Cognito JSON ウェブトークンの署名をデコードして検証するにはどうすればよいですか?」 も参考にしてください。


今回は、今後のアーキテクチャや実装の目指す方向を整理し、マイクロサービスを保護するために本連載で導入するOAuth2 Loginについて説明しました。 次回以降は、当環境のアプリケーションでOAuth2 Loginを実現するための認証・認可サーバとして利用するAmazon Cognitoについて説明し、環境を構築していきます。


著者紹介

川畑 光平(KAWABATA Kohei) - NTTデータ エグゼクティブ ITスペシャリスト ソフトウェアアーキテクト・デジタルテクノロジーストラテジスト(クラウド)

../_images/aws_361383_0752.jpeg

金融機関システム業務アプリケーション開発・システム基盤担当、ソフトウェア開発自動化関連の研究開発を経て、デジタル技術関連の研究開発・推進に従事。

Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなど様々な開発プロジェクト支援にも携わる。

AWS Top Engineers & Ambassadors 選出。

本連載記事の内容に対するご意見・ご質問は Facebook まで。