DVA_EN

Change Permission for Guest/Sign-in users in Cognito ID Pool

スポンサーリンク
Change Permissions for Guest/Sign-in users in Cognito ID Pool DVA_EN
スポンサーリンク
スポンサーリンク

Change Permission for Guest/Sign-in users in Cognito ID Pool

The Cognito ID pool can generate temporary credentials for unauthenticated guest users in addition to authenticated users.
In this case, we will check a configuration that grants different privileges to guest sign-in users.

Environment

Diagram of change permissions for guest/sign-in users in Cognito ID Pool.

Create an S3 bucket and enable the static website hosting feature.
Prepare content by placing HTML files inside.

Create a sign-in function in the hosted UI of the Cognito user pool.

Configure the Cognito ID pool to assign privileges to guest sign-in users.
Specifically, create two Lambda functions and configure each to be executed by the corresponding user.

CloudFormation template files

The above configuration is built with CloudFormation.
The following URL contains the CloudFormation template, browser scripts, etc.

awstut-dva/03/003 at main · awstut-an-r/awstut-dva
Contribute to awstut-an-r/awstut-dva development by creating an account on GitHub.

Explanation of key points in template files

To change permissions between sign-in users and guest users, we will review the Cognito ID pool, focusing on the configuration.

Attach IAM roles for guest and sign-in users to Cognito ID pool

The way to authorize users in the Cognito ID pool is to attach the corresponding IAM role.

Resources: IdentityPool: Type: AWS::Cognito::IdentityPool Properties: AllowUnauthenticatedIdentities: true CognitoIdentityProviders: - ClientId: !Ref UserPoolClient ProviderName: !Sub "cognito-idp.${AWS::Region}.amazonaws.com/${UserPool}" IdentityPoolName: !Sub "${Prefix}-IdentityPool" IdentityPoolRoleAttachment: Type: AWS::Cognito::IdentityPoolRoleAttachment Properties: IdentityPoolId: !Ref IdentityPool Roles: authenticated: !GetAtt IdentityPoolAuthenticatedRole.Arn unauthenticated: !GetAtt IdentityPoolUnauthenticatedRole.Arn
Code language: YAML (yaml)

The ID pool itself does not require any special configuration.
It is simply configured to work with the user pool.

The point is to attach IAM roles.
In this case, we will assign different privileges to sign-in and guest users, so we will set up IAM roles using the authenticated and unauthenticated properties, respectively.

This time we will define the following IAM roles

Resources: IdentityPoolAuthenticatedRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRoleWithWebIdentity Principal: Federated: cognito-identity.amazonaws.com Condition: StringEquals: cognito-identity.amazonaws.com:aud: !Ref IdentityPool ForAnyValue:StringLike: cognito-identity.amazonaws.com:amr: authenticated Policies: - PolicyName: IdentityPoolAuthenticatedPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - lambda:InvokeFunction Resource: - !Ref AuthenticatedFunctionArn IdentityPoolUnauthenticatedRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRoleWithWebIdentity Principal: Federated: cognito-identity.amazonaws.com Condition: StringEquals: cognito-identity.amazonaws.com:aud: !Ref IdentityPool ForAnyValue:StringLike: cognito-identity.amazonaws.com:amr: unauthenticated Policies: - PolicyName: IdentityPoolUnauthenticatedPolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - lambda:InvokeFunction Resource: - !Ref UnauthenticatedFunctionArn
Code language: YAML (yaml)

Set the conditions for assuming the IAM role in the Condition property.
Please refer to the following page for details.

Role trust and permissions - Amazon Cognito
Example trust policy for Amazon Cognito.

In the Policies property, define the privileges to be granted.
Specify a Lambda function to allow execution.

Lambda functions to invoke

Although not related to Cognito, check the Lambda function definitions.

Resources: AuthenticatedFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${Prefix}-AuthenticatedFunction" Runtime: python3.9 Role: !GetAtt LambdaRole.Arn Handler: index.lambda_handler Code: ZipFile: | import datetime def lambda_handler(event, context): return str(datetime.date.today()) UnauthenticatedFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${Prefix}-UnauthenticatedFunction" Runtime: python3.9 Role: !GetAtt LambdaRole.Arn Handler: index.lambda_handler Code: ZipFile: | import datetime def lambda_handler(event, context): return str(datetime.datetime.now().time())
Code language: YAML (yaml)

Describe the code to be executed inline.
For more information on how to define a Lambda function, please see the following page

Select Python 3.9 as the runtime environment and configure each to perform the following

  • Function for signed-in users: Returns today’s date.
  • Function for guest user: Returns the current time.

Browser Script

Use JavaScript to implement Cognito functionality after sign-in.
For instructions on how to create a browser script using AWS SDK for JavaScript v3, please refer to the following page.

This page will focus on content related to the sorting of guest and sign-in users.

Obtaining ID Token

In this configuration, the OAuth flow is set to Implicit Grant.
With Implicit Grant, an ID token can be obtained from the URL parameter.
In the case of a signed-in user, the following code can be used to obtain an ID token.

const params = new URLSearchParams(location.hash.slice(1)); const idToken = params.get("id_token");
Code language: JavaScript (javascript)

For more information, please see the following page.

Create Lambda client according to user

Create a client object to access the Lambda function.
The key point is to separate the responses according to the presence or absence of an ID token.

import { CognitoIdentityClient } from "@aws-sdk/client-cognito-identity"; import { fromCognitoIdentityPool } from "@aws-sdk/credential-provider-cognito-identity"; import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda"; import { toUtf8 } from "@aws-sdk/util-utf8-browser"; let lambdaClient; let functionName; if (idToken) { lambdaClient = new LambdaClient({ region: REGION, credentials: fromCognitoIdentityPool({ client: new CognitoIdentityClient({ region: REGION }), identityPoolId: IDENTITY_POOL_ID, logins: { [`cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}`]: idToken } }), }); functionName = FUNCTION_NAME_AUTHENTICATED; } else { lambdaClient = new LambdaClient({ region: REGION, credentials: fromCognitoIdentityPool({ client: new CognitoIdentityClient({ region: REGION }), identityPoolId: IDENTITY_POOL_ID }), }); functionName = FUNCTION_NAME_UNAUTHENTICATED; }
Code language: JavaScript (javascript)

In the case of a signed-in user, the aforementioned code can be used to obtain an ID token.
Therefore, the client object is created using that token.

On the other hand, in the case of a guest user, the ID token cannot be obtained because the user has not signed in.
Therefore, the client object is created without the ID token.

This client object will use credentials based on the IAM role attached to the identity pool.
In other words, the privileges are set according to the user.

Lambda Function Invocation

The process after this is common.
Execute a Lambda function using the client object.

(async () => { const response = await lambdaClient.send( new InvokeCommand({ FunctionName: functionName }) ); document.getElementById("function-result").innerText = toUtf8(response.Payload); })();
Code language: JavaScript (javascript)

Execute a Lambda function and embed the execution result in HTML.
As mentioned earlier, the function is executed within the scope of the privileges granted by the credential.

HTML file

HTML is also checked for reference.

<html> <head></head> <body> <h1>index.html</h1> <p id="function-result"></p> <ul> <li> <p><a href="https://[domain].auth.ap-northeast-1.amazoncognito.com/login?response_type=token&client_id=[client-id]&redirect_uri=[redirect-url]/index.html">Sign In</a></p> </li> <li> <p><a href="https://[domain].auth.ap-northeast-1.amazoncognito.com/logout?client_id=[client-id]&logout_uri=[redirect-url]/index.html">Sign Out</a></p> </li> </ul> <script type="text/javascript" src="./main.js"></script> </body> </html>
Code language: HTML, XML (xml)

Embed the result of the Lambda function execution within a p tag with a class name of function-result.

Place a URL for sign-in and sign-out.
Set the redirect URL to point to this index.html.

Architecting

Use CloudFormation to build this environment and check actual behavior.

Create CloudFormation stacks and check resources in stacks

Create a CloudFormation stack.
For information on how to create stacks and check each stack, please refer to the following page

Place content in S3 buckets

Place HTML and JavaScript files in the S3 bucket.

Two files are uploaded to the S3 bucket.

These two files are the contents after sign-in/sign-out.

Verification: Access as guest user

Now that we are ready, we can actually access the contents.
Access the following URL

https://s3-ap-northeast-1.amazonaws.com/dva-03-003/index.html

Functions for guest users were executed.

The current time is displayed.
Since you are not signed in at this time, this means that you are accessing this page as a guest user and the Lambda function for guest users was executed.

Verification: Accessing as signed-in user

The sign-up/sign-in process is then performed.
Please refer to the following page for details.

Once the sign-up/sign-in is completed, you will be redirected to this page again.

Functions for Sign-in users were executed.

The current date is now displayed.
This means that the sign-in process generated an ID token and executed the Lambda function for the signed-in user.

(Reference) ID pool

For reference, let’s check the Identity generated in the steps up to this point.

Two Identities have been created.
Two Identities have been created.

As you can see, two Identities have been created.
This means that not only a sign-in user, but also an Identity for the guest user was created, and a Lambda function for the guest was executed with it.

Summary

We have identified a way to change permissions for guest and sign-in users.
Specifically, the IAM role for the guest sign-in user is attached in the ID pool, and the process is branched depending on whether the user has an ID token or not.

タイトルとURLをコピーしました