IAM認証をかけたAPI GatewayにCognitoユーザープールのユーザーでアクセスする
Goal
アプリ側で作成したCognitoユーザーがIAM認証をかけたAPIにアクセスし、レスポンスデータが確認できる
現状
こちらの記事を参考にして以下のことまでできている
・APIの認可設定でIAMを設定
・AWS CLIに設定していた自身のアクセスキー、シークレットキーでPostmanからアクセス
次のアクション
- 用意したAPIにアクセスができるようになるIAMポリシーを作成する
- CognitoのユーザーにIAMポリシーをアタッチする
- IAMロールがアタッチされたユーザーと、そうでないユーザーとでアプリ側からアクセスを試す
IAMポリシーの設定はこちらの記事参考にするとミニマムでできそうで良き
1.用意したAPIにアクセスができるようになるIAMポリシーを作成する
この投稿内容は誤りです
正しくは、この投稿内容にぶら下がっている返信を確認してください
ビジュアルエディタで作成してみたのでSidという属性が入ってるみたい
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "apigateway:GET",
"Resource": "arn:aws:execute-api:ap-northeast-1:XXXXXXXXXXXX:YYYYYYYYYY/*/GET/ZZZZZZ"
}
]
}
余談:IAMポリシーの作成をビジュアルエディタでできるんですね
なお、ビジュアルエディタで進めていたら警告出ましたが、が動作に問題あるのか???
ポリシーを作成しようと思ったらAPI Gatewayの設定が2つあって戸惑った
下記リンクのリファレンスと、Zennの記事を見て分かる通り内容が異なる。
-
Amazon API Gateway Management
Amazon API Gateway Management で定義されるアクション -
Amazon API Gateway Management V2
Amazon API Gateway Management V2で定義されるアクション
(V1)とV2どっち使う?
今回はREST APIで作成を進めていたのでV1の方を選択します。
ブラーだらけですが、赤枠のREST APIが今回の動作検証で使っているものです。
上記、間違いでした。
アクションの選択ではExcute APIを選択します。
でもって、こんな感じに設定します。
違和感持っておいてよかったとは思えど、解決に時間かかった、、、
2.CognitoのユーザーにIAMポリシーをアタッチする
正確には「Cognitoユーザープール内のユーザーグループ単位でIAMロールを設定して、APIへのアクセス制御を実現したい」ということです。
なお、ユーザーグループへの登録は、Cognitoユーザーのアカウント確認後をトリガーとしてLambdaを設定し、そのLambda内でする予定です。
補足ですがこの確認後トリガーはAPI GatewayやLambda側からは選択できないため、Cognitoの画面から行う必要があります(自分調べ)。
冒頭の文章を書いてから、この文章を書き始めるまでに2時間くらい混乱してあっち行ってこっち行ってを繰り返してましたが、例のごとくクラスメソッドさんがめちゃくちゃいい記事を書いていて、「これが言いたかったんだよこれが」となったので貼っておきます。
躓いた箇所を一応残しておきます。
Cognitoのユーザープール内でユーザーグループを作成するのは直感的ですぐ分かって、操作も簡単で、すぐにできるです。その一方で、ユーザープールに対してIAMロールを割り当てようとした時に、Principalの部分(=”信頼されたエンティティ”、つまり誰が・何が行うかの部分)に指定できる情報の中に、ユーザープールのグループを示すようなものがありませんでした。その代わりにIDプールを指定するような仕様になっていて、理解の浅かった私はかなり混乱していました。
「今はユーザープールのユーザーグループに対してIAMロール設定したいのに、なぜPrincipalにはIDプールしか指定できないんだ?」と。
その答えは上記のクラスメソッドさんの記事で紹介されているのでこちらでは割愛します。
2.CognitoのユーザーにIAMポリシーをアタッチする(続き)
混乱が解けたので作業を進めていきます。先のクラスメソッドさんの記事を参考にして”Cognitoユーザープールのユーザーに設定したIAM Roleで一時クレデンシャルキーを発行してみる”をやっていきます。
割当てるロールの作成
- IAMロールの新規作成
- ”ウェブアイデンティティ”を選択してIDプールの情報を入力
- 本稿「1.用意したAPIにアクセスができるようになるIAMポリシーを作成する」で作成したポリシーを選択
- ロール名や説明を入力して作成
補足
手順2でIDプールの情報を入力する際に、”条件”を追加できます。ここの条件は2種類から選べて、それぞれ下記のような意味を持ちます。
-
cognito-identity.amazon.com:sub
Cognitoユーザープールに属するユーザーのことを指します。
ユーザーの詳細を表示するページに遷移すると、ユーザーID(Sub)となっています。
-
cognito-identity.amazon.com:amr
こちらはChatGPTによると、、、(怠惰の極み)
"amr"は"Authentication Methods Reference"の略語です。この値は、ユーザーがAmazon Cognitoを使用して認証する際に使用された認証メカニズムを示します。たとえば、"pwd"はパスワード認証を示し、"saml"はSAMLベースの認証を示します。これにより、ユーザーがどのように認証されたかを確認し、特定の認証方法を使用したユーザーに対して異なるアクセス権を与えることができます。
だそうです。なお、SubはSubjectのSubだとか。
キャプチャ
-
”ウェブアイデンティティ”を選択してIDプールの情報を入力
-
本稿「1.用意したAPIにアクセスができるようになるIAMポリシーを作成する」で作成したポリシーを選択
2.CognitoのユーザーにIAMポリシーをアタッチする(続き)
IAMロールが作成できたので、CognitoグループへそのIAMロールの紐付けの設定と、CognitoIDプール側がそのIAMロールを割り当てられるようにする設定の2つを行います。
CognitoグループへそのIAMロールの紐付け
簡単なので手順だけ軽く載せておきます。
- ユーザープールにアクセス
- ユーザーグループを選択(無い場合は新規作成)
- ユーザーグループを編集
CognitoIDプール側がそのIAMロールを割り当てられるようにする
こちらの簡単なので手順だけ
- IDプールにアクセス
- IDプールを編集
- 認証プロバイダーを選択
- 認証されたロールの選択で”トークンからロールを選択”に設定
3.IAMロールがアタッチされたユーザーと、そうでないユーザーとでアプリ側からアクセスを試す
AWS側での設定作業はこれで完了です。
AWS CLIを利用して動作確認することも出来ますが、ここは手元で作成を進めているアプリで動作確認をしてみます。
あと、紛らわしいので念の為、、
-
IAMロールがアタッチされたユーザー
今回の設定を施したCognitoユーザープールのグループに所属するユーザー -
そうでないユーザー
同じCognitoユーザープールだが、今回の設定を施していないグループに所属するユーザー
なんか怒られた
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: CognitoClientException{statusCode: 400, code: InvalidIdentityPoolConfigurationException, name: InvalidIdentityPoolConfigurationException, message: Invalid identity pool configuration. Check assigned IAM roles for this pool.}
ここか?
それっぽい表示、、
Before you can begin using your new Amazon Cognito identity pool, you must assign one or more IAM roles to determine the level of access you want your application end users to have to your AWS resources. Identity pools define two types of identities: authenticated and unauthenticated. Each can be assigned their own role in IAM. Authenticated identities belong to users who are authenticated by a public login provider (Amazon Cognito user pools, Facebook, Google, SAML, or any OpenID Connect Providers) or a developer provider (your own backend authentication process), while unauthenticated identities typically belong to guest users.
When Amazon Cognito receives a user request, the service will determine if the request is either authenticated or unauthenticated, determine which role is associated with that authentication type, and then use the policy attached to that role to respond to the request. For a list of fine-grained IAM role example policies to choose from, see IAM Roles in the Amazon Cognito Developer Guide.
Note
As a best practice, define policies that follow the principle of granting least privilege. In other words, the policies should include only the permissions that users require to perform their tasks. For more information, see Grant Least Privilege in the IAM User Guide. Remember that unauthenticated identities are assumed by users who do not log in to your app. Typically, the permissions that you assign for unauthenticated identities should be more restrictive than those for authenticated identities.
解決しました!
上記の設定ですが、Cognito IDプールが、Cognitoユーザープールと連携したりなんやかんやして、きめ細かいIAMロールの設定(今回のようなグループごとのIAMロールの設定など)をするために必要みたいですね。そのほかにも正確には分からないですが、cognito-syncはCognitoユーザープールに登録されている、ユーザーごとの属性を編集したりするためのものかな?と思いました。
ChatGPTさんでサクッと解説
このJSONは、IAMロールまたはIAMユーザーに関連付けられたIAMポリシーを表します。このポリシーには、3つのアクション(mobileanalytics:PutEvents、cognito-sync:、cognito-identity:)が含まれており、それらのすべてに"Allow"の許可が設定されています。これらのアクションによって、モバイルアプリのアナリティクスイベントをAmazon Mobile Analyticsに送信したり、Amazon Cognito Syncサービスを使用したり、Amazon Cognito Identityサービスを使用したりすることができます。
また、"Resource"に"*"が指定されているため、このポリシーによって、このアカウント内のすべてのリソースに対してこれらのアクションを許可することができます。ただし、このポリシーがどのIAMロールまたはIAMユーザーに関連付けられているかに応じて、このポリシーが実際に適用される範囲は異なります
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*",
"cognito-identity:*"
],
"Resource": [
"*"
]
}
]
}
3.IAMロールがアタッチされたユーザーと、そうでないユーザーとでアプリ側からアクセスを試す
こちらの動作確認ですが、設定当初うまく行かず、ユーザーにIAMロールが付与されていない状態が続いていました。
CognitoIDプール側の設定変更の反映が遅いのかと思って少しまったり、念の為設定をし直したりしたところ、無事、ユーザーにIAMロールが付与されて適切なアクセス制御を実現することができました。