- For application user management, authentication & authorization
- Basic concepts:
- User pool : handles user registration, authentication etc of your own web application
- Identity pool : authorize user to access AWS resources, where those users (id) can be from user pool, or other ID providers (such as Facebook, Google).
- Further reading on user pool vs. id pool, https://serverless-stack.com/chapters/cognito-user-pool-vs-identity-pool.html
- Group
- One user one group
- In conflict, check precedence
- Work scenario:
- Sign in with user pool, get user pool token - which also carries group id
- Exchange user pool token for temporary AWS credentials through identity pool
- Access AWS service with AWS credential
User pool (User Management and Authentication for Your Apps)
- Everything about user authentication (security etc.)
- Attributes
- All member have a directory profile accessible through SDK
- Configure what is required at sign on
- Policies - password policy, enable/disable user sign on
- MFA
- Advanced security - separate pricing, adaptive authentication...
- Message customization
- Devices - tracing user devices, can suppress MFA
- App clients (See below)
- Triggers - Lambda at life cycle event
- Analytics - to create user campaigns
- App integration
- Per app client settings (OAuth2.0)
- Use own domain name (with AWS Certificate Manager (ACM))
- Built-in, customizable web UI
- Federation
- 3rd party IdP
- Attribute mapping
- Generate client secret
- generate a secret for server client to use
- do NOT generate secret if there is no server side (browser cannot keep a secret)
- Alternative authentication process options:
- Enable sign-in API for server-based authentication (ADMIN_NO_SRP_AUTH)
- SRP approach is recommended. This one is not.
- Does not support device tracking
- API accept clear password
- Only allow Custom Authentication (CUSTOM_AUTH_FLOW_ONLY)
- can help create a challenge/response-based authentication model using AWS Lambda triggers
- Enable username-password (non-SRP) flow for app-based authentication (USER_PASSWORD_AUTH)
App client settings (not required if NOT using built-in UI)
- Enable at least one ID providers
- Sign-in / sign-out URL
- OAuth 2.0 flow (see OAuth2.0)
- Authorization code grant (return code, in redirect URL, then server use the code to get the access token)
- Return code in redirect URL
- User agent then access server with that URL, server exchange the code for token at TOKEN endpoint
- For mobile apps, recommended with PCKE
- Require a server
- Implicit grant
- Allow client get access token (optionally ID token) directly from AUTHORIZATION end point
- Less secure (since client get token)
- When there is no server to exchange code for token, use implicit grant
- OAuth2.0 scope - access scope for client
- Domain name - use aws or own domain name for authorization UI
- UI customization - no i18n (yet)
- Basic UI URL
Authentication Method and Flow
Authentication can be a flexible and complex process.
SRP is the default and recommended protocol to use: "client demonstrate knowledge of password without sending the password; password never leaves client and is unknown to server"
After initial authentication with username/email with password, server may sends back challenges, and client should respond to the challenge, provide user with UI to input the response, and send the response to server.
If uses Cognito Identity SDK (the call back style) as in the example, the call back methods are called in accordance with the server challenge. The behavior (when the call back is called) is determined by the authentication flow.
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html
https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html
Authentication flow can be customized with lambda, see
https://aws.amazon.com/blogs/mobile/customizing-your-user-pool-authentication-flow/
Work with User Pool Tokens
On success authentication, the result object contains three tokens according to OpenID Connect (OIDC) open standard:
- ID Token (resultObject.idToken)
- is JWT token
- Purpose: Contains claims of who the authenticated user is
- Expires by default 1 hour after authentication
- Payload include claims such as:
- sub: the subject's UUID
- iss: issuer, such as in format https://cognito-idp.{region}.amazonaws.com/{userPoolId}
- aud: audience, the client id in the authenticated user (something cannot relate to other data)
- token_use: intended purpose, always 'id' in ID token
- auth_time: when the authentication occurred, not the time when token was issued (on refresh)
- also contain user attributes
- Access Token
- is JWT token
- Purpose: "Authorizes API operations in the context of the user in the user pool" (such as update attributes)
- Expires by default 1 hour after authentication
- Payload includes:
- sub: subject UUID
- iss: issuer, https://cognito-idp.{region}.amazonaws.com/{userPoolId}.
- token_use: 'access'
- auth_time: original authentication time, not token issue time (on refresh)
- scope: resource server hosts protected resources (AWS or not), and can define scopes (e.g. read, read+write), app can request custom scope during authentication process and then can be granted the scope in the Access Token. app can then present the access token, and resource server, after verifying the signature and expiry time of the access token, decide if allow access. See "Defineing Resource Servers" in User Pool / App Integration, and also API-Gateway / cognito authorizer / access token based authorization.
- others, see demo
- Refresh Token
- NOT JWT token
- Purpose: retrieve new ID & Access tokens until Refresh token itself expires
- Expires by default 30 days after user authentication.
- Mobile SDK (for iOS & Android automatically refresh tokens)
- To refresh, use the AdminInitiateAuth or InitiateAuth methods.
Revoke All Tokens for a User
- Users can sign out from all devices where they are currently signed in when you revoke all of the user's tokens by using the GlobalSignOut and AdminUserGlobalSignOut APIs
About JWT Token
- Is a standard
- Has header, payload & signature
- Header & signature are used for verification
- Payload contains claims
- Can use online tools https://jwt.io/ to decode and verify
- Can find many libraries to decode & verify
- If use token to decide access (like on a server), first VERIFY token before trusting any of the claims
ID pool (Federated Identities & Authorization for AWS Resources)
- Issues temporary AWS credentials
- Support anonymous user
- Accept a list of ID providers including user pool & 3rd party ID providers (IdP)
- Integrate with user pool to save profile information
- Inside an ID pool
- Allow anonymous, (and/or)
- User source : user pool, 3rd parties (Facebook, Google...)
- Authenticated role / Unauthenticated role (permission to logged in / not logged in user)
- Push synchronization (push changes to device)
- Cognito Streams (integration with AWS Kinesis stream)
- Cognito Events (integrate with Lambda)
- Sample code
- Authenticate with user pool
- Access AWS service
- Create groups
- Give an IAM role
- Assign user to group
- Access AWS service through API Gateway & Lambda
- API Gateway validate token
- API Gateway grant access to Lambda etc.
- AmazonCognito authorizer Lambda function - verify
- Access AWS service with user pool & id pool
- Access with 3rd party IdP & Identity pool
- Access AWS AppSync Resources with AmazonCognito
- AUTHORIZATION
- TOKEN
- USERINFO
- LOGIN
- LOGOUT
See https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-userpools-server-contract-reference.html
The Amazon Cognito Identity SDK - core library to interact with user pool
The Amazon Cognito Identity SDK for JavaScript is now part of the AWS Amplify Library.
The above also provides dozens of examples. Note some example also used Amplify library (so needs integration)
To integrate with existing Vue application (webpack template)
- > npm install --save-dev webpack json-loader
- > npm install --save amazon-cognito-identity-js
- In build/webpack.base.conf.js, add "{ test: /\.json$/, loader: 'json-loader' }" in module/rules
- Cognito user pool: create, and obtains pool ID and app ID (no app secret cause client cannot keep it)
Documents & Code examples:
https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-integrating-user-pools-javascript.html
https://docs.aws.amazon.com/cognito/latest/developerguide/using-amazon-cognito-user-identity-pools-javascript-examples.html
- This is a more complete examples page, better than that on github, with MFA & attribute examples, etc.
https://github.com/aws/aws-amplify/tree/master/packages/amazon-cognito-identity-js/
Best chance to quickly master this library is to (1) follow the examples (2) examine the live objects with browser developer tool (and Vue tool) and (3) check source code.
The Amazon Cognito Auth SDK - leverages the built-in UI, use to add web pages for app for: sign-up, sign-in, confirmation, multi-factor authentication (MFA), and sign-out. Haven't tried it.
AWS Amplify - a declarative JavaScript library, "what to do instead of how to do it"
Code samples: https://aws.github.io/aws-amplify/media/authentication_guide
- sample looks like more straight forward, and uses javascript Promise style .then(), .catch()
- automatically refresh tokens
Further read my Amplify notes.
AWS SDK
"Each API operation is exposed as a function on service"
Also manages the ID pool session.
To integrate:
- >npm install --save aws-sdk
- var AWS = require('aws-sdk');
Documentation
AWS.CognitoIdentityServiceProvider: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html
- AWS.config.region - the default region
- AWS.config.credentials = new AWS.CognitoIdentityCredentials(...) - the credentials (ID Pool)
- AWS.config.credentials.refresh(...) - obtain / refresh the ID pool session
- getUser - get user information including MFA preference (otherwise not able to get from Cognito Identity SDK) - var provider = new window.AWS.CognitoIdentityServiceProvider(); provider.getUser(params, handler)...
- initiateAuth - initiate authentication flow, provide flow type as parameter,
Managing User Pool Security
Multi-Factor Authentication (MFA)
MFA Method:
- SMS
- Phone must be verified
- Default SMS spending limit per account US$1. Submit an SNS Limit Increase Case with AWS Support to raise the limit. (see here)
- Time-based one-time (TOTP)
Mode:
- Off
- Option (required to work with adaptive authentication)
- Required : can only enable at pool creation
Modes:
- on: and customize actions in response to different risks (see below)
- audit mode: only gather metrics, and publish to Amazon CloudWatch
Compromised Credentials
- Cognito can detect (1) compromised elsewhere (2) easy to guess credentials (username/password)
- Options:
- Check when: sign in, sign up, password change (multi-choice)
- Allow: allow but publish attempts to CloudWatch
- Block: block and require user change password
Adaptive Authentication
Require second factor authentication upon increased risk level.
Risk
- Upon each sign-in attempt a risk score is calculated based on many factors (IP, location, device, etc.) ranging from "No Risk" to "High Risk"
- Sign-in attempts, risk levels, failed challenges, etc. publishes to Amazon CloudWatch
Options
- Allow
- Optional MFA - user who has MFA required second factor, who has not MFA allowed
- Require MFA - user who has MFA required second factor, who has not blocked
- Block
Advanced Security Metrics
Available at CloudWatch