There is some ambiguity in the docs...
These docs seem to imply that pre-signup is called only during signup and first-time (?) external provider login. The only trigger source constants mentioned are:
PreSignUp_SignUp
PreSignUp_AdminCreateUser
PreSignUp_ExternalProvider
However, the ForgotPassword doc mentions calling it as well:
When you use the ForgotPassword API action, Amazon Cognito invokes any functions that are assigned to the following triggers: pre sign-up, custom message, and user migration.
In general is there a definitive, accurate source of what Cognito Lambdas are called for which user/api actions?
Below is AWS's response to my comment on their docs page. In short pre-sign-up is NOT run on ForgotPassword.
We recently received feedback from you about the following page in the
Cognito documentation:
https://docs.aws.amazon.com/en_us/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html
Your comments were:
What I'm trying to do: ...
What to make better: Does InitiateAuth trigger pre-signup? Its a bit
ambiguous in the ClientMetadata section. Really each of these docs
should have a section on lambdas invoked or better, a chart of how and
when (for instance, ForgetPW is a three part process - when are the
various lambdas invoked??)
I'm sorry that you're having difficulty finding the information you
need. The sources for Pre sign-up triggers are listed at link [1]. The
function runs when you run the SignUp and AdminCreateUser APIs, as
well as when you sign in for the first time using an external
provider. The triggers that you can run on InitiateAuth are Pre
Authentication, Post authentication, Define/Create/Verify custom auth,
pre token generation, custom message, and migrate user.
Link [1] also describes the triggers associated with a ForgotPassword
process. You can run post confirmation, pre token, migrate user, and
custom message functions.
Thanks for taking the time to send us feedback! We appreciate all
feedback, whether it's positive or it alerts us to a problem we need
to address. Please don't hesitate to contact us with any other
feedback you might have about our documentation.
[1] Customizing user pool workflows with Lambda triggers - User pool Lambda trigger sources - https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#cognito-user-identity-pools-working-with-aws-lambda-trigger-sources
Related
I want to create OTP based authentication using AWS cognito (CUSTOM_AUTH), all resources I saw were having 3 triggers(defineauth, createauth etc). Can I implement custom auth without using them ?
You need all three. The first (Define Auth Challenge) lets you define the cognito auth statemachine execution (can include built in challenges). The second (Create Auth Challenge) sets up the challenge and defines the values to check against. The last (Verify Auth Challenge Response) lets you perform tests against the response and define whether the challenge succeeded. That gets passed back into the state machine which calls back to the first handler (Define Auth Challenge) which is where you can declare whether the user successfully authenticated.
Amazon has some examples of their own. I've seen a few random tutorials post flows that have security flaws so I'd stick with AWS for this.
Email OTP example can be found here.
AWS Cognito SDK provides two methods:
GetUserAttributeVerificationCode
VerifyUserAttribute
The first one generates a 4-digit code for the provided attribute (email or phone) and the second one verifies the provided attribute with the provided code.
I want to use my own service for sending SMS verification codes. Unfortunately, AWS doesn't seem to provide an API, where I can manually set a 4-digit code on a cognito user awaiting confirmation inside something like a custom attribute phone_code_verification and then call VerifyUserAttribute to verify that code.
Is there a way to achieve this ?
Also, AWS Cognito throws LimitExceededException, TooManyRequestsException and other useful errors, so I would like the proposed method to be wrapped in the same AWS logic and not have to implement rate limit or request limits myself.
I've been exploring OneLogin and I think I have a basic understanding of how to use it; I was successful at configuring the Node+Passport sample application to authenticate with OneLogin and I understand the code.
I want to try it with AWS API Gateway. I've got an API already defined in AWS. On a high level I know I need to configure an Authorizer in AWS for OneLogin and that there is going to be some bit of information that I will need to pass in a header when I make my calls to the AWS Api Gateway (I assume a Bearer token that I get from authenticating with OneLogin before I interact with AWS, but I don't know).
Can someone give me a description of what I need to do? The most recent question that I see here on the topic was posted in 2016 back when the answer was "You can't do that." That answer has changed in the past 4 years. The OneLogin documentation says it can be done, but I have found not information on how to do it.
GENERAL PATTERN
The role of an authorizer function is to perform the following actions:
Validate access token
Optionally collect additional claims
Cache the claims for subsequent requests with the same token
Provide claims to business logic
In fact this is a general pattern that can be used anywhere, as referenced in my blog post.
TOKEN VALIDATION
I would use the One Login Introspection Endpoint.
Some NodeJS code of mine that calls an introspection endpoint is here.
AWS SPECIFICS
Since you are using OneLogin you will need to write some custom code. Your lambda authorizer will need to do standard OAuth 2.0 work, then return an AWS policy document. Some resources of mine may help you to understand how this works:
Lambda Authorizer Blog Post
Associated NodeJS Code
PAIN POINTS
The AWS plumbing is a bit painful, and it is possible you are using some different technology choices to me - I am using the Serverless Framework.
Hopefully though, this gives you something to run locally and compare against. Happy to answer any follow up questions ...
I have read the AWS Amplify API and I have found some weird thing.
I've found 2 similar functions
currentAuthenticatedUser() and currentUserPoolUser().
They have the same description, parameters, and returns.
I want to know why they separated.
[reference]
https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#currentauthenticateduser
https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#currentuserpooluser
I believe user pool users are those that are from Cognito, whereas an authenticated user is one that come from an identity pool (from a federated identity).
See: https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pools-identity-pools/
From the code, it looks like currentAuthenticatedUser checks for federation info. However, if it doesn't find federation info, it just calls currentUserPoolUser. So I'd say call currentUserPoolUser if you know you're never going to be using federated logins, but you should probably call currentAuthenticatedUser if there's a chance you might.
according to amplify auth docs, both result in "A promise resolves to current authenticated CognitoUser if success"
Wondering if it's possible to combine using the client credentials OAuth flow in Cognito with a custom authentication flow as described here: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-challenge.html
I know about custom authentication flows in Cognito, but I am not so well versed in OAuth itself. But as far as I understand it, the client credentials flow, is unrelated to a user? Because in that case, I would think it is impossible to use a custom authentication flow since the SDK documentation states the following (taken from the AWS node.js SDK):
The authentication parameters. These are inputs corresponding to the AuthFlow that you are invoking. The required values depend on the value of AuthFlow:
[...] For CUSTOM_AUTH: USERNAME (required)
If the value passed as USERNAME in the CUSTOM_AUTH flow is not a known user in Cognito, the lambda trigger for the custom flow will never be executed. And since it is never executed, it is not possible to use the USERNAME parameter to pass any other data to the lambda trigger (you can of course use custom authentication parameters, but you also need a valid USERNAME).