How to get cognito user's "username" in cloudformation - amazon-web-services

I created a user like:
SuperAdminUser:
Type: AWS::Cognito::UserPoolUser
Properties:
DesiredDeliveryMediums:
- EMAIL
Username: !Ref SuperAdminEmail
UserAttributes:
- Name: email
Value: !Ref SuperAdminEmail
UserPoolId:
Fn::ImportValue:
!Sub ${BaseStack}-Cognito
And the user pool is defined:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
AdminCreateUserConfig:
AllowAdminCreateUserOnly: false
UnusedAccountValidityDays: 3
LambdaConfig:
PreSignUp: !GetAtt CognitoPreSignUpHook.Arn
Policies:
PasswordPolicy:
MinimumLength: 8
RequireNumbers: true
UsernameAttributes:
- email
I noticed that it fails to find the user because username looks like: 9f8aecc2-530d-411d-8d73-c3b775da1893 while !Ref gives the email of the user in this case. I notice this started failing when I added
UsernameAttributes:
- email
How can I resolve this? I noticed User resource does not allow me to get the Sub of the user ...

Related

Cognito use either email or phone number as username

I have this SAM template:
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: >
Passwordless SMS authentication backend using Amazon Cognito User Pools CUSTOM AUTH challenge flow w/ AWS Lambda triggers and Amazon SNS for sending SMS TOTP
Metadata:
AWS::ServerlessRepo::Application:
Name: passwordless-sms-email-auth
Description: >
Passwordless SMS authentication backend using Amazon Cognito User Pools CUSTOM AUTH challenge flow w/ AWS Lambda triggers and Amazon SNS for sending SMS TOTP
SpdxLicenseId: MIT
LicenseUrl: LICENSE
Labels: ['passwordless', 'authentication', 'cognito', 'auth', 'sms', 'iOS', 'mobile', 'pinpoint', 'serverless', 'amplify']
SemanticVersion: 1.14.20
Globals:
Function:
Timeout: 3
Parameters:
UserPoolName:
Type: String
Description: The name you want the User Pool to be created with
Default: rafaelTest
Resources:
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: !Ref UserPoolName
Schema:
- Name: name
AttributeDataType: String
Mutable: true
Required: true
- Name: phone_number
AttributeDataType: String
Mutable: true
Required: false
- Name: email
AttributeDataType: String
Mutable: true
Required: false
Policies:
PasswordPolicy:
MinimumLength: 6
RequireLowercase: false
RequireNumbers: false
RequireSymbols: false
RequireUppercase: false
UsernameAttributes:
- phone_number
- email
MfaConfiguration: "OFF"
LambdaConfig:
CreateAuthChallenge: !GetAtt CreateAuthChallenge.Arn
DefineAuthChallenge: !GetAtt DefineAuthChallenge.Arn
PreSignUp: !GetAtt PreSignUp.Arn
VerifyAuthChallengeResponse: !GetAtt VerifyAuthChallengeResponse.Arn
UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: sms-auth-client
GenerateSecret: false
UserPoolId: !Ref UserPool
ExplicitAuthFlows:
- CUSTOM_AUTH_FLOW_ONLY
Outputs:
UserPoolId:
Description: ID of the User Pool
Value: !Ref UserPool
UserPoolClientId:
Description: ID of the User Pool Client
Value: !Ref UserPoolClient
When creating the userpool, I wanted users to be able to use either just their email or just their phone as their username.
This way it is done, I always need to send both email and phone number.
Does anyone know how I solve this?
I want users to be able to log in by putting one of the following information:
email + name
phone number + name
Anyone help me?
Users can login with their email or phone number, using this SAM template and use a random uuid as username when sign up.
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: !Ref UserPoolName
Schema:
- Name: phone_number
AttributeDataType: String
Mutable: true
- Name: email
AttributeDataType: String
Mutable: true
Policies:
PasswordPolicy:
MinimumLength: 6
RequireLowercase: false
RequireNumbers: false
RequireSymbols: false
RequireUppercase: false
AliasAttributes:
- email
- phone_number
MfaConfiguration: "OFF"
But now I need to know with alias users use on sign in, anyone know how?
i'm doing a passwordless flow with cognito and the event on create-auth-lambda triggers is always the same.

Aws sam cognito api gateway - access token forbidden but works if it's from postman

I have a CognitoUserPool and a lambda function that requires an authenticated user.
When making a request with the token acquired from postman that opens the aws UI login, it works, but when using the token from a curl login it doesn't got 403 forbidden, any idea of what I'm missing?
My template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Env:
Type: String
Default: dev
AllowedValues:
- dev
- test
- prod
Description: >-
sam-app
Transform:
- AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 100
Runtime: nodejs16.x
MemorySize: 128
Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: !Sub ${Env}-Cognito-User-Pool
Policies:
PasswordPolicy:
MinimumLength: 8
UsernameAttributes:
- email
AutoVerifiedAttributes:
- email
Schema:
- AttributeDataType: String
Name: email
Required: false
CognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
UserPoolId: !Ref CognitoUserPool
ClientName: !Sub ${Env}-CognitoUserPoolClient
GenerateSecret: false
CallbackURLs:
- http://localhost:3000
LogoutURLs:
- http://localhost:3000
AllowedOAuthFlowsUserPoolClient: true
ExplicitAuthFlows:
- ALLOW_ADMIN_USER_PASSWORD_AUTH
- ALLOW_USER_PASSWORD_AUTH
- ALLOW_CUSTOM_AUTH
- ALLOW_USER_SRP_AUTH
- ALLOW_REFRESH_TOKEN_AUTH
- ALLOW_USER_PASSWORD_AUTH
AllowedOAuthFlows:
- code
- implicit
SupportedIdentityProviders:
- COGNITO
AllowedOAuthScopes:
- openid
- email
- profile
CognitoDomainName:
Type: AWS::Cognito::UserPoolDomain
Properties:
Domain: !Sub ${Env}-domain-test
UserPoolId: !Ref CognitoUserPool
HttpApi:
Type: AWS::Serverless::HttpApi
DependsOn: CognitoUserPoolClient
Properties:
StageName: !Ref Env
Auth:
Authorizers:
CustomCognitoAuthorizer:
UserPoolArn: !GetAtt CognitoUserPool.Arn
AuthorizationScopes:
- email
IdentitySource: "$request.header.Authorization"
JwtConfiguration:
issuer: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${CognitoUserPool}
audience:
- !Ref CognitoUserPoolClient
CorsConfiguration:
AllowMethods:
- GET
AllowHeaders: '*'
AllowOrigins:
- '*'
getAllItemsFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/get-all-items.getAllItemsHandler
Events:
DosGet:
Type: HttpApi
Properties:
Auth:
Authorizer: CustomCognitoAuthorizer
Path: /
ApiId: !Ref HttpApi
Method: GET
The curl that I use to login, got it from this post AWS - Cognito Authentication - Curl Call - Generate Token Without CLI - No Client Secret
Method: POST
Endpoint: https://cognito-idp.{REGION}.amazonaws.com/
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Body:
{
"AuthParameters" : {
"USERNAME" : "YOUR_USERNAME",
"PASSWORD" : "YOUR_PASSWORD"
},
"AuthFlow" : "USER_PASSWORD_AUTH", // Don't have to change this if you are using password auth
"ClientId" : "APP_CLIENT_ID"
}
After a bit of digging, I solved the issue, by analyzing the token that was generated from each method I saw a difference.
The token acquired from the aws UI.
{
"scope": "aws.cognito.signin.user.admin"
}
And the one from curl login
{
"scope": "openid profile email"
}
So the solution was to add aws.cognito.signin.user.admin as part of my UserPoolClient AllowedOAuthScopes
AllowedOAuthScopes:
- openid
- email
- profile
- aws.cognito.signin.user.admin
and on my HttpApi AuthorizationScopes
AllowedOAuthScopes:
- email
- aws.cognito.signin.user.admin

Serverless Cognito - Sign Up with Username, Password, and Email

I am having trouble implementing Cognito via Serverless. The AWS Cognito documentation is poor. What I want to do is:
Allow user to sign up with a unique username (coolprogrammer69), a unique email, and password
After sign up, allow user to modify username (coolprogrammer69 -> awesomeprogrammer69) and email as long as it is unique
This is a typical auth flow for a forum website like Stackoverflow; however, I cannot find the right combination of attributes to make this a reality. Can you please help me figure out what I am doing wrong?
service: my-cool-infrastructure
package:
individually: true
provider:
name: aws
runtime: nodejs14.x
environment:
user_pool_id: { Ref: UserPool }
client_id: { Ref: UserClient }
iamRoleStatements:
- Effect: Allow
Action:
- cognito-idp:AdminInitiateAuth
- cognito-idp:AdminCreateUser
- cognito-idp:AdminSetUserPassword
Resource: "*"
functions:
login:
handler: user/login.handler
events:
- http:
path: user/login
method: post
cors: true
register:
handler: user/register.handler
events:
- http:
path: user/register
method: post
cors: true
privateAPI:
handler: user/private.handler
events:
- http:
path: user/private
method: post
cors: true
authorizer:
name: PrivateAuthorizer
type: COGNITO_USER_POOLS
arn:
Fn::GetAtt:
- UserPool
- Arn
claims:
- email
resources:
Resources:
UserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: my-cognito-pool
Schema:
-
Name: email
Mutable: true
Required: true
-
Name: preferred_username
Mutable: true
Required: true
Policies:
PasswordPolicy:
MinimumLength: 8
RequireNumbers: true
RequireSymbols: true
UserClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: user-pool-ui
GenerateSecret: false
UserPoolId: { Ref: UserPool }
AccessTokenValidity: 5
IdTokenValidity: 5
ExplicitAuthFlows:
- "ADMIN_NO_SRP_AUTH"

AWS CloudFormation template to use Cognito

I have been trying to add a User Pool using AWS cloud formation template but it fails on the Deploy executechange set stage.
CognitoUsers:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: MoreLinksUsers-pool
UsernameConfiguration:
CaseSensitive: false
AdminCreateUserConfig:
AllowAdminCreateUserOnly: true
Policies:
PasswordPolicy:
MinimumLength: 8
RequireLowercase: true
RequireSymbols: true
RequireUppercase: true
TemporaryPasswordValidityDays: 1
UsernameAttributes:
- email
MfaConfiguration: "OFF"
Schema:
- AttributeDataType: String
DeveloperOnlyAttribute: false
Mutable: true
Name: email
ClientAppClient:
Type: AWS::Cognito::UserPoolClient
Properties:
UserPoolId: !Ref CognitoUsers
ClientName: ClientApp
GenerateSecret: false
RefreshTokenValidity: 30
AllowedOAuthFlows:
- code
- implicit
ExplicitAuthFlows:
- ALLOW_USER_SRP_AUTH
- ALLOW_REFRESH_TOKEN_AUTH
# CallbackURLs: !Ref AllowedCallbacks
AllowedOAuthScopes:
- email
- openid
- profile
- aws.cognito.signin.user.admin
AllowedOAuthFlowsUserPoolClient: true
PreventUserExistenceErrors: ENABLED
SupportedIdentityProviders:
- COGNITO
Any attribute that I'm missing? Any advice would be greatly appreciated. Thanks.

How to require email validation in Cognito through CloudFormation?

I think I tried all properties here:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-userpool.html
couldn't get this box checked:
My config currently:
CognitoUserPoolGeneral:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: general
Policies:
PasswordPolicy:
MinimumLength: 6
RequireLowercase: false
RequireNumbers: false
RequireSymbols: false
RequireUppercase: false
Schema:
- AttributeDataType: String
Name: preferredLocale
DeveloperOnlyAttribute: false
Mutable: true
Required: false
EmailVerificationMessage: "Here's your verification code: {####}. Please provide it inside the application."
EmailVerificationSubject: "subject"
You can add
AutoVerifiedAttributes:
- email
To your Properties key, like so:
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: !Sub ${AuthName}-user-pool
AutoVerifiedAttributes:
- email
Policies:.....
For an excellent example of a CloudFormation template that creates Cognito resources, see:
https://gist.github.com/singledigit/2c4d7232fa96d9e98a3de89cf6ebe7a5