Last active
May 2, 2022 15:17
-
-
Save amcginlay/b2ee81e8d2e603042f322528535480fd to your computer and use it in GitHub Desktop.
Demo steps for Cognito User Pools and Identity Pools
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Cognito User Pool Demo with Chalice> | |
PART 1 | |
- Create a new user pool (e.g. apm-demo-user-pool), click Review Defaults and create pool | |
- Show User and groups -> (empty) | |
- Show Policies -> deselect all password checkboxes (keep things simple) and save changes | |
- Show General settings / App clients -> | |
--- Add | |
--- set App client name (e.g. apm-demo-app-client) | |
--- Disable Generate client secret (so later call to "aws cognito-idp initiate-auth" doesn't barf) | |
--- Enable username based password authentication (the 3rd of 5 options - ALLOW_USER_PASSWORD_AUTH) | |
--- Client Create app client | |
--- Note App client ID (if necessary) | |
- Show App client settings -> | |
--- Locate your app client by ID (may only be one ATM) | |
--- Select Enabled Identity Providers -> Select All (includes Cognito User Pools) | |
--- Set callback URL (e.g. https://www.example.com - NOTE "http" not supported) | |
--- OAuth2 Flows -> Enable Implicit grant (without this we cannot launch a hosted UI) | |
--- OAuth2 Scope -> Enable email and openid (will error unless both selected) | |
--- Click Save changes (NOTE host UI unavailable until Domain Name specified) | |
- Go to Domain name -> | |
--- Set Domain prefix as appropriate (e.g. apm-demo) | |
--- Click Check availability | |
--- Click Save changes | |
- Go back to App client settings for your app client ID and click Launch hosted UI | |
- Click Sign up | |
- Generate and copy an email address from https://www.guerrillamail.com | |
- Fill in Sign Up form with User (please use "alan"), Email and Password | |
- ... DON'T wait for the Emailed Verification Code ... | |
- Show User and groups -> (no longer empty but one is Account status UNCONFIRMED) | |
- Select the UNCONFIRMED user and click "Confirm User" (if short on time) | |
- Once more, go back to App client settings again and click Launch hosted UI | |
- Sign in to see how Cognito decorates the URL as it navigates to https://www.example.com | |
- Use the following commands to extract the id_token from that URL ... | |
url="<URL>" # --- DON'T FORGET THE QUOTES! | |
echo ${url} | cut -d'#' -f2 | cut -d'&' -f1 | cut -d'=' -f2 | |
- ... and enter it into https://jwt.io/ (note this displayes the username and email) | |
PART 2 | |
- Grab the AWS resource IDs | |
user_pool_id=$(aws cognito-idp list-user-pools --max-results 5 --query 'UserPools[?Name==`apm-demo-user-pool`].Id' --output text) | |
user_pool_arn=$(aws cognito-idp describe-user-pool --user-pool-id ${user_pool_id} --query 'UserPool.Arn' --output text) | |
app_client_id=$(aws cognito-idp list-user-pool-clients --user-pool-id ${user_pool_id} --query 'UserPoolClients[0].ClientId' --output text) | |
- Use Chalice to build a serverless app behind API Gateway (perhaps SAM or CDK?) | |
--- run "pip install chalice" | |
--- run "chalice new-project apm-demo && cd apm-demo" | |
--- Open app.py for orientation purposes | |
--- run "chalice deploy" | |
--- update app.py as follows (note the use of user_pool_arn env var) | |
------ | |
cat <<EOF > ~/environment/apm-demo/app.py | |
from chalice import Chalice | |
from chalice import CognitoUserPoolAuthorizer as cpa | |
app = Chalice(app_name='apm-demo') | |
auth = cpa( | |
'apm-demo-user-pool', provider_arns = ['${user_pool_arn}'] | |
) | |
@app.route('/secret', authorizer = auth) | |
def secret(): | |
return {'open': 'sesame'} | |
@app.route('/') | |
def index(): | |
return {'hello': 'world'} | |
EOF | |
------ | |
--- again, run "chalice deploy" | |
--- test endpoint (curl) -> "/" should be authorized but "secret" is unauthorized | |
- Click around in API Gateway, show authorizers | |
- Authenticate with user pool to generate tokens (note the use of app_client_id env var here) | |
--- aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id ${app_client_id} --query 'AuthenticationResult.IdToken' --output text --auth-parameters USERNAME=alan,PASSWORD=<PASSWORD> | |
- NOTE you extract the <IdToken> JWT for API Gateway ... <AccessToken> is similar but more typically used for OAuth/OIDC | |
- Use Postman with "TYPE: No Auth" to call unsecured endpoint | |
--- / -> works! | |
- Use Postman with "TYPE: No Auth" to call secured endpoint | |
--- /secret -> "Unauthorized" | |
--- Change to "TYPE: Bearer Token" and paste in the <IdToken> | |
--- /secret -> works! | |
- Use Postman to hook out the curl syntax so you can reproduce the /secret demo in your terminal | |
- Go to https://jwt.io and paste in the <IdToken> (or <AccessToken> for comparison) | |
- [Consider extending this to federate in with Okta] | |
<Cognito Identity Pool Demo> | |
- Identity pool return AWS credentials | |
- authenticated (e.g. S3-Full) OR unauthenticated (e.g. S3-Read) | |
- Identity pool has no user directory | |
- Create a new Identity Pool (e.g. apm-demo-identity-pool) | |
- Set authenticated and unauthenticated roles | |
- Show Unauthenticated identities | |
--- Set Enable access to unauthenticated identities | |
- Show Authentication providers ... use: echo ${user_pool_id} && echo ${app_client_id} | |
--- Set Cognito User Pool ID | |
--- Set Cognito App client Id | |
- Grab the Identity Pool ID | |
--- identity_pool_id=$(aws cognito-identity list-identity-pools --max-results 5 --query 'IdentityPools[?IdentityPoolName==`apm-demo-identity-pool`].IdentityPoolId' --output text) | |
- [ USING UNAUTHENTICATED ROLE ] | |
- Generate an temp user (IdentityId) and associated credentials | |
--- unauth_id=$(aws cognito-identity get-id --identity-pool-id ${identity_pool_id} --query 'IdentityId' --output text) | |
--- creds=($(aws cognito-identity get-credentials-for-identity --identity-id ${unauth_id} --query 'Credentials.[AccessKeyId,SecretKey,SessionToken]' --output text)) | |
--- echo ${creds[*]} # just to see what we have | |
--- AWS_ACCESS_KEY_ID=${creds[0]} AWS_SECRET_ACCESS_KEY=${creds[1]} AWS_SESSION_TOKEN=${creds[2]} aws sts get-caller-identity | |
- ************ NOT WORKING !!!!! *************** | |
- [ USING AUTHENTICATED ROLE - NOT WORKING!!!, I've tried swapping out AuthenticationResult.IdToken for AuthenticationResult.AccessToken but to no avail ?!?!?!? ] | |
--- alan_password=<PASSWORD> | |
--- auth_token=$(aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id ${app_client_id} --query 'AuthenticationResult.IdToken' --output text --auth-parameters USERNAME=alan,PASSWORD=${alan_password}) | |
--- auth_id=$(aws cognito-identity get-id --identity-pool-id ${identity_pool_id} --logins cognito-idp.us-west-2.amazonaws.com/${user_pool_id}=${auth_token} --query 'IdentityId' --output text) | |
[NOTE the rest is the same as UNAUTH] | |
--- creds=($(aws cognito-identity get-credentials-for-identity --identity-id ${auth_id} --query 'Credentials.[AccessKeyId,SecretKey,SessionToken]' --output text)) | |
--- AWS_ACCESS_KEY_ID=${creds[0]} AWS_SECRET_ACCESS_KEY=${creds[1]} AWS_SESSION_TOKEN=${creds[2]} aws sts get-caller-identity |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment