5
1

Cognitoユーザプールの外部IdP連携をちゃんと理解する

Last updated at Posted at 2023-12-24

これまで認証といえばCognito一択みたいにアーキを描いて、あとはいい感じに連携してくれているみたいな理解で実際その裏で何がされているかを気にしてこなかった。AWS SAPの対策でやたらID連携が出てきたり、仕事上認証認可の細かいところを触れることがあり一度整理する。

[そもそも] 認証認可の周辺知識整理

■ 認証と認可

認証 → 相手が誰かを同定する作業。ステータスコード401はリクエスタが誰だかわかってない状態。
認可 → 相手に権限を与える作業。ステータスコード403は誰だかわかった上で許可しない状態。

■ OAuth2.0

認可のためのプロトコル。
以下のメリットがある。

  • クライアントアプリにリソースを提供したいがID/PWは渡したくない。
  • PWのライフサイクルと分離したい。(ID/PWを渡すとPW変更のたびにアクセス権が失われるため)
  • 部分的に権限を渡したい。(ID/PWだとアクセスする全ての操作ができることになってしまうため)

→ アクセストークンを用いてクライアントがリソースへアクセスできるようにしたもの。アクセストークンは予測不可能な文字列などが利用される。

image.png

4種類のフロー

(1) Client Credentials Grant

結局、クライアントに埋め込まれた client ID / secret をアクセストークンに引き換えてるだけ。
永続的なクライアントのクレデンシャルを一時的なアクセストークンに変えることで一定の安全になるもののこのフローでできることはユーザに関連しない情報を取得することしかできない。(リソースオーナーを介さないので。)
用途としては公式アプリクライアントがログイン状態不問で実施する処理を行う場合など。(未ログイン状態で表示する情報をリソースサーバから取得する際にクライアントをチェックする目的。)

image.png

(2) Resource Owner Password Credentials Grant

結局、ユーザ ID / PW をアクセストークンに引き換えてるだけ。
ClientがID/PWを知ってしまうので悪意のあるClientだとなりすまされる可能性がある。
公式クライアントなどでしか利用できない方法。
もはや使ってはいけないとまで言われてる。

image.png

(3) Implicit Grant

モバイルやブラウザ上のJSアプリなどエンドユーザ支配下にあるノードの上で動くアプリケーション向け。パブリッククライアントと呼ばれる。クライアントシークレットを保護できないため割り当てない。
このフローはクライアントにID/PWを渡さないがユーザエージェントにはアクセストークンが丸見え。
これも今では非推奨らしい。

image.png

なお、このフローは認可横取り攻撃に脆弱である。悪意のあるClientが認可コードを正しいClientへリダイレクトせず認可コード、アクセストークンが横取りされうる。
これに対しPKCE (Proof Key for Code Exchange by OAuth Public Client)という対策が作られた。これは検証用文字列(コードチャレンジ)を生成し、そのハッシュ化法を予めサーバに通知しておくことで認可リクエストと認可コードの送り主が一緒かをサーバ側で検証できるようにする手法である。

(4) Authorization Code Grant

OAuthの理想が詰まったフロー。clientにだけアクセストークンを渡すことができる。
サーバサイドWebアプリClientなど安全にクライアントシークレットを保存できるノードで動くアプリケーション向け。

image.png

(appendix) リフレッシュトークンフロー

ここはOAuthで標準化された範囲外。

image.png

まとめ

基本型のAuthorization Code Grantに照らしてOAuthの全体図を書くと以下。

image.png

■ OpenID Connect

OAuthが一般的になるにつれてOAuthを認証に使われるようになった。
これはとても危険。当然ながらトークンを持っている=本人ではないから。

→ 認証部分をカバーした拡張仕様としてOpenID Connectが生まれた。
OpenID ConnectではOAuth2.0に以下の点を加えている。

  • IDプロバイダ(IdP, OP)にて認可だけではなく認証を実施
  • アクセストークンとともにIDトークンを返却する。
  • クライアント側ではIDトークンをIdPの公開鍵で検証する。

以下のバリエーションがある。

  1. Basic Client Profile (OAuth2.0のAuthorization Code Grantの拡張)
  2. Implicit Client Profile (OAuth2.0のImplicit Grantの拡張)

ここでは前者について考える。

Basic Client Profile

OAuth2.0(Authorization Code Grant)に重ねると以下の感じ。

image.png

[本題] Cognitoって何してるの?

結局ブラックベルトが一番理解を進めてくれた気がする。
https://aws.amazon.com/jp/blogs/news/webinar-bb-amazon-cognito-2020/

image.png
(▲ BlackBeltより転載)

Cognitoユーザプールの使い方には大きく2種類ある。

  1. 認証UIを自前実装しCognito Identity Provider APIを利用して認証・各種トークンのやりとりを行う。 (※用語が古いのかCognito IdP APIのリファレンスがヒットせず、おそらく今ではCognitoユーザプールAPIのことと解釈した。)
  2. Cognitoが提供するHosted UIをフロントとしCognito Auth APIを利用して認証・各種トークンのやりとりを行う。(※用語が古いのかCognito Auth APIのリファレンスがヒットせず、おそらく今ではCognitoフェデレーションエンドポイントのことと解釈した。*1)

*1 : 緒言としては弱いが、2,3年前の以下の記事の参考にてCognito Auth APIリファレンスへのリンクが記載されており、開くといずれもCognitoフェデレーションエンドポイントとHosted UIについて触れたページに飛んだため一旦その理解で進めた。

当初この2パターンという分け方の認識がずれていて理解に時間がかかった。
ここがわかるとあとはシーケンスで理解ができる。

Hosted UIを使うケース

このケースがよく使われるのはそもそもWebコンテンツをダウンロードさせる前に認証をかけ、Lambda@Edgeで弾く場合に使われている印象。(偏見かも)
ここではLambda@EdgeでCognitoとやりとりして認証する場合で書く。
RPってどこに該当するんだと悩んだが結局IdPとやりとりして認証を行うのはLambda@EdgeになることからおそらくCF+L@EがRPと考えた。

①-A Hosted UI + CognitoをIdPとするケース

image.png

①-B Hosted UI + CognitoをOIDCに準拠した外部IdPと連携するケース

なおidentity_provider=xxxxxと外部IdPをクエリパラメータで明示的に指定しておくことでHosted UIをスキップ可能。

image.png

Hosted UIを使わずCognito APIをコールするケース

SPAを利用する場合によく使われてるイメージ。
最初にSPAのコンテンツを取得するの自体はできるが、認証を必要とするリソースへのアクセスの際には認証画面を表示する。この時にHosted UIが出てくる構成を使ってるのはあまり見たことがない。(偏見かも)
amplify UIのAuthenticatorクラスみたいなやつを使って表示させていたような気がするのでそこに合わせて書く。
同じくどこがRPなのか問題だが、①と違いこっちはL@Eがなく認証APIの処理はブラウザ上で動くSPAになるのでこいつがRPになると考えた。

②-A 自前UI + CognitoをIdPとするケース

image.png

②-B 自前UI + Cognitoを外部IdPと連携するケース

image.png

SAML連携

Cognitoコンソールで連携するIdPを追加する画面を確認すると、SAMLも選択可能であることが見える。

image.png

認証のプロトコルであるSAMLのIdPを選択した場合、認可に係るトークン発行などの部分はCognitoがカバーしてくれるということと予想。

image.png
公式ドキュメントより転載。

OIDCでは/oauth2/idpresponseにリダイレクトしたが、ここではSAMLアサーションを受け取って/saml2/idpresponseにリダイレクトすることでトークンが返るのだと思う。

image.png

参考

蛇足

閉域網でのCognito利用

シーケンスに出てきたCognitoの各種エンドポイントはいずれもパブリックIPアドレス(実際にはDNS名)で公開されており、閉域網で利用できない。
以下にプライベートサブネットからどうアクセスするかのバリエーションが示されているのをみつけたがいずれもインターネットに出る必要がある。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1