LoginSignup
0
0

AWS Cognito で Client Credentials Grant をやってみた

Posted at

はじめに

Amazon Cognito は、固有の User API を使った認証に加えて、OAuth 2.0 認証フレームワークをサポートしています。OAuth 2.0 は、いくつかの認証フローが RFC で定義されています。例えば、次のようなものがあります。

  • Authorization code grant : ユーザー認証で利用される基本的な方式
  • Implicit grant : 「Authorization code grant」が利用できない特別な利用が有る場合にのみ利用する方式
  • Client credentials grant : システム間の連携で利用される方式

詳細は次の英語 Blog で説明されています。
https://aws.amazon.com/jp/blogs/mobile/understanding-amazon-cognito-user-pool-oauth-2-0-grants/

この記事では、「Client credentials grant」を利用する方法を検証してみる内容です。「Client credentials grant」を利用するシチュエーションは次を想像しています。

  • システム間の認証で利用する。具体的には、**「AWS 外」**のシステムから、AWS 上の API Gateway を呼びだす。
  • この時に特定のシステムのみアクセスを許可したい。

**「AWS 外」**と強調しているのは、AWS 内のアクセスでは、あえて「Client credentials grant」を利用しなくても良い場合があります。例えば、EC2 から API Gateway にアクセスしたいときに、API Gateway の認証方式で「AWS IAM」を選択可能です。これによって、特定の IAM Role を持っている EC2 インスタンスに限定できるので、こちらの方が最適な場合が考えられます。

ということで、「Client credentials grant」の検証を進めてみましょう!

Cognito : User Pool を作成

まず Cognito の User Pool を作成します。既に User Pool を持っている場合は、この章は無視して頂いて大丈夫です。

image-20230604211122338.png

「Client credentials grant」にはあまり関係がないですが、ユーザー属性として Email を選択します。

image-20230604211243353.png

Password Policy は Default のままです。

image-20230604211321756.png

使わないですが、MFA は Optional にしてみます。

image-20230604211445404.png

このあたりも Default のままです。

image-20230604211411015.png

このあたりも Default のままです。

image-20230604212021485.png

適当に指定します。

image-20230604212124835.png

Userpool 名を入力します。

image-20230604212317920.png

Hosted UI の利用を ON にします。

client-credentials-grant

image-20230604212407982.png

画面上、App Client を作成しないといけないです。後で削除するので、適当な名前を入力します。

image-20230604213404238.png

Create を押します。

image-20230604213713195.png

User Pool が作成されました。

image-20230604213738044.png

Cognito : Resource Server を作成

次に、Cognito User Pool 上で Resource Server の定義が必要です。

作成した User Pool を選択します。

image-20230604214506405.png

App integration のタブを選択します。

image-20230604214555071.png

Create resource server のボタンを押します。

image-20230605004503230.png

この Resource Server の名前は任意の好きなもので大丈夫です。Scope も指定します。

client-credentials-grant-resource-server

image-20230605004808096.png

Cognito : App Client を作成

次に、Cognito 上で App Client を作成します。App integration のタブを選択します。

image-20230604214555071.png

以前作成した Dummy の Application Client を削除します。

image-20230604214638904.png

その後、Create app client を押します。

image-20230604215136564.png

Confidential client を生成します。

client-credentials-grant-test01

image-20230604215407543.png

このあたりはデフォルトです。

image-20230604221346436.png

使わないですが、callback url を適当にします。

image-20230604221501072.png

ポイントがここです。Client credentials を選択し、Custom scppes も指定します。

image-20230605004950367.png

Create を押します。

image-20230604221618700.png

生成されました。Client ID と Client Secret を後で使うため、メモっておきます。

image-20230605005100985.png

API Gateway と Lambda に紐づけ

「Client credentials grant」の動作確認をするために、API Gateway と Lambda を準備します。REST API のものを作成します。

image-20230605005753443.png

適当にリソースを作成して、Lambda 関数を紐づけます。

image-20230605010011030.png

API Gateway に、Cognito のオーソライザーを紐づけるために、Authorizers のメニューから作成します。

Authorization

image-20230605010157899.png

Authorizer が作成されました。

image-20230605010220424.png

対象のリソースに、Authorizer を紐づけます。

image-20230605010309299.png

Authorization と OAuth Scopes をします。OAuth Scopes は、Cognito 上で定義したものを指定します。

client-credentials-grant-resource-server/test

image-20230605010529549.png

Deploy を押します。

image-20230605010619880.png

Deploy を押します。

image-20230605010938190.png

動作確認

実際に、「Client credentials grant」で Token を取得して、API Gateway にアクセスできるか試してみましょう。

まず、Token が無い状態で API Gateway にアクセスしてみると、想定通りエラーになります。

> curl -X POST https://emtlsn2nuc.execute-api.ap-northeast-1.amazonaws.com/prod/hello
{"message":"Unauthorized"}

Token を入手するための Cognito の Domain URL を調べます。

https://client-credentials-grant.auth.ap-northeast-1.amazoncognito.com

image-20230605012025322.png

Token を取得するために、curl で Cognito のエンドポイントにアクセスします。APP_CLIENT_ID や CLIENT_SECRET, TOKEN_END_POINT は環境に合わせて書き換えてください。

  • Cognito 上で生成した Client ID と Client Secret を使って、Base64 でエンコードする
  • エンコードで得られた文字列をリクエストヘッダー Authorization に入れる
# 事前準備
APP_CLIENT_ID=himitsu1
CLIENT_SECRET=himitsu2
TOKEN_END_POINT=https://client-credentials-grant.auth.ap-northeast-1.amazoncognito.com
CODE=`echo -n ${APP_CLIENT_ID}:${CLIENT_SECRET} | base64 -w 0`

# トークン取得
curl -X POST ${TOKEN_END_POINT}/oauth2/token \
-H "Authorization: Basic $CODE" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" | jq .

実行例 : 次のように Access Token が取得できます。この Access Token を使って API Gateway にアクセスができます。

{
  "access_token": "eyJraWQiOiJsK25WZTd.....省略......CmA",
  "expires_in": 3600,
  "token_type": "Bearer"
}

access_token を変数に格納します。

access_token=$(curl -X POST ${TOKEN_END_POINT}/oauth2/token \
-H "Authorization: Basic $CODE" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
--data-urlencode 'scope=client-credentials-grant-resource-server/test' | jq -r .access_token)

確認です。

echo $access_token

次のように curl で API Gateway にアクセスします。リクエストヘッダーに、access_token を指定します。

curl -X POST \
-H "Authorization:$access_token" \
https://emtlsn2nuc.execute-api.ap-northeast-1.amazonaws.com/prod/hello

以下のように、Lambda の実行結果が返ってくれば OK です!

$ curl -X POST \
> -H "Authorization:$access_token" \
> https://emtlsn2nuc.execute-api.ap-northeast-1.amazonaws.com/prod/hello
{"statusCode": 200, "body": "{\"message\": \"hello world\"}"}

検証を通じてわかったこと

  • Cogitno で 「Client credentials grant」でアクセスが可能
  • Cognito のマネージメントコンソールにある App Client の画面で「Client credentials grant」周りの設定が可能

参考 URL

0
0
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
0
0