Custom phone verification in AWS Cognito? - amazon-web-services

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.

Related

During which actions is AWS Cognito Lambda `Pre-signup` invoked?

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

Is it necessary to use triggers in CUSTOM_AUTH of AWS cognito?

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.

Resending phone_number attribute verification code in AWS Cognito

Is there a way in AWS SDK CognitoIdentityServiceProvider to resend a phone_number attribute change verification code for a CONFIRMED user?
I have set phone_number attribute to be verified in Cognito. adminUpdateUserAttributes() sends the verification code. But I have failed to find a way of resending the verification code. This is a necessity in the use case i am working on.
So far I have tried doing a adminUpdateUserAttributes() with the same phone number. It doesn't seem like it resend the verification code. With a new number, it does.
I cant do a deleteUserAttributes() and an update again, as the pool configuration sets the phone number as required.
Not sure if its relevant; but note that I have to pretty much use the CognitoIdentityServiceProvider admin APIs as Sign UP is also disabled in the User pool.
To sum it up, I am looking for a solution where I can resend the verification code for phone_number attribute in a confirmed user in Cognito User Pool.
This is the method in AWS Api reference that resends OTP code for this flow:
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUserAttributeVerificationCode.html
Then in my service, using AWS Java SDK, I call it:
public void resendCodeAttributeVerification(String accessToken) {
cognitoClient.getUserAttributeVerificationCode(new GetUserAttributeVerificationCodeRequest()
.withAttributeName(PHONE_NUMBER)
.withAccessToken(accessToken));
}

Combine client_credentials and Custom authentication flow in Cognito?

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).

'Unauthorized' when using Cognito User Pool Authorizer

So I had an API (let's call it API number 1) and one user pool. The API was used for testing purposes. It called a lambda function to update an IOT shadow. Now I used cognito to create a user pool and added some users in it. Then, I created an authorizer for API number 1 with the same user pool and enabled authorization in POST method execution for it. I created a login form so that I could log into cognito user pool and would get an ID token from it. I used that id token in POSTMAN along with Authorization header and the post worked. When I did not provide the id token, I got message: unauthorized as a response. The IOT shadow was updated only when I provided the authorization header and id token which meant everything went smoothly.
Then for testing purpose I created another API (API number 2), I replicated API number 1 entirely, created an authorizer with the same pool, enabled Authorization, logged in, got the id token used it in POSTMAN with Authorization header (the same process) and it didn't work. I kept getting message: unauthorized.
Then I thought maybe the problem was with API number 2 and created API number 3. This time I also created an entirely new user pool. I used that user pool to create an authorizer. The rest, I replicated API number 1 entirely again. I enabled CORS, in POST method execution I added Authorization. I did everything. Still when I tried again with POSTMAN, it didn't work.
So, API number 1 still functions perfectly like it should. API 2 and API 3 do not work despite having the exact same configurations as API 1.
I really do not know where I am going wrong. I even tried creating separate lambda functions for each API. Even the lambda code is the same (except for the IOT certificates and the IOT shadow URL).
Please, Help!! At this point I think I have tried almost everything and still I don't know whats wrong. One seems to work with the same configuration that the other two have whereas the other two don't. Thanks alot in advance.