amplify-js
amplify-js copied to clipboard
PreAuthentication trigger not triggered in Custom Auth Flow
** Which Category is your question related to? ** Auth
** What AWS Services are you utilizing? ** Cognito
** Provide additional details e.g. code snippets **
I have an issue with the Cognito PreAuthentication trigger not triggered when an user sign-in
We are using a Cognito user pool with only CUSTOM_AUTH_FLOW_ONLY
auth to do a passwordless authentication system.
I my CloudFormation template I have configured a lambda to handle the trigger :
# ...
PreAuthentication:
Type: AWS::Serverless::Function
Properties:
CodeUri: build/lambda-triggers/pre-authentication/
Handler: pre-authentication.handler
Runtime: nodejs12.x
# ...
PreAuthenticationInvocationPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt PreAuthentication.Arn
Principal: cognito-idp.amazonaws.com
SourceArn: !GetAtt UserPool.Arn
# ...
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: !Ref UserPoolName
Schema: # ...
Policies: # ...
UsernameAttributes:
- email
MfaConfiguration: "OFF"
LambdaConfig:
CreateAuthChallenge: !GetAtt CreateAuthChallenge.Arn
DefineAuthChallenge: !GetAtt DefineAuthChallenge.Arn
PreSignUp: !GetAtt PreSignUp.Arn
PreAuthentication: !GetAtt PreAuthentication.Arn # Here
VerifyAuthChallengeResponse: !GetAtt VerifyAuthChallengeResponse.Arn
PostAuthentication: !GetAtt PostAuthentication.Arn
# ...
UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: email-auth-client
GenerateSecret: false
UserPoolId: !Ref UserPool
ExplicitAuthFlows:
- CUSTOM_AUTH_FLOW_ONLY
For now the lambda implementation is useless:
import { CognitoUserPoolTriggerHandler } from "aws-lambda";
export const handler: CognitoUserPoolTriggerHandler = async (
event,
context
) => {
console.log(event, context);
// return event;
throw new Error("Is this really executed?");
};
When I deploy the lambda it appear correctly in the Cognito UI as the registered trigger.
But impossible to have the function to be executed on sign in (nor sign up):
const newCognitoUser = await AmplifyAuth.signIn({
username: email,
password: "",
validationData: { some_data: "foo_bar" },
});
# No PreAuthentication lambda triggered
# Others triggers works perfectly.
Is this an issue Aplify or is that an issue with my understanding of the auth process?
Have you tried utilizing the Amplify CLI to configure Cognito with a Lambda trigger?
I did not have try the Amplify Cli but the Cognito GUI and Cloud Formation deployment template. Is the CLI is mandatory?
Hi @Spy-Seth - the CLI flow is recommended. You could spin up a sample project with the CLI and let us know if that works? This will help determine if it's a potential issue. This doc will help you get started -> https://docs.amplify.aws/cli/usage/lambda-triggers#cognito-lambda-triggers
@mauerbac I work with @Spy-Seth and we have an example repository to reproduce the issue.
BTW we've not used Amplify CLI here but terraform. At the end it's the very same I guess. We've also used a cognito cloudformation stack in another try and every time we have this same issue with the never invoked pre authentication lambda.
Could it be related to auth flows we allow?
@shouze can you see the validationData
as part of the data request?
@shouze : I dont see how the validationData is being passed in. From the code, I only see email is sent in.
For pre authentication or pre sign up, it is important to pass in validationData - https://docs.amplify.aws/lib/auth/advanced/q/platform/js#pre-authentication-and-pre-sign-up-lambda-triggers
@ashika01 ok yes will try that, If I remember well we've already tried and that didn't works but I prefer to double check.
@shouze yeah let us know how it goes.
@ashika01 I've tried with no more luck (I've tried both variants with username as a string and validation data as third argument, validation data in signinOpts as first argument, nor more arguments) https://github.com/Spy-Seth/cognito-passwordless-bug/commit/d0be033d9f987d125ffed5344a955e684223f7f0#diff-da5998deda0a56bb613b4fe12ae4eef9R22-R29
Moreover I can confirm you that my browser network inspector as the proof that the payload effectively contains validation data (but, transformed as client metadata):
as I have it as validationData until initiateAuth get called into the debugger:
transformed/normalized later on:
Here it was just about the signin part, same thing with signup.
According to the doc this normalization sounds OK https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#API_InitiateAuth_RequestSyntax
On my side, impossible to have preAuth Working It prevents the logging leaving no trace in cognito, no log log for the Lambda like if it was never called I enable preAuthTrigger through CloudFormation the code now is the sample from the doc :
exports.handler = async (event, context, callback) => {
if (event.callerContext.clientId === "user-pool-app-client-id-to-be-blocked") {
var error = new Error("Cannot authenticate users from this user pool app client");
// Return error to Amazon Cognito
callback(error, event);
}
// Return to Amazon Cognito
callback(null, event);
};
The lambda is defined and exported in a CDK Stack The Userpool is defined and its triigered attached in cloud Formation PosAuth works fine BTW the lambda works fine tested from lambda console
Very annoying
After contacting the AWS support it's a know bug: the pre-authentification hook is not called on custom auth flow
Would be nice to see it fixed though
I can confirm this is not an issue with Amplify library, is a restriction by Cognito User Pools.
Why do you need validation data and custom challenge, those seems to be similar to me. Maybe I am missing another use case.
Thanks
@Spy-Seth have you heard more regarding the bug? I am also finding that the pre-authentication trigger is not called while using custom auth flow. This was the only thread I could on the topic so far.
@reedyrm We have no news about this bug. We are waiting to see if this bug is resolved
@elorzafe I miss your message sorry. We a are looking to inject validation data (a token in our case) in the login process to be able to open the passwordless link in another device than the one than generate it: start to use you mobile, check your mail on the desktop and click on it, and get back back to the same point.
here is the way, how I did multienv support:
"Conditions": { "CurrentEnvIsLive": { "Fn::Equals": [ { "Ref": "env" }, "live" ] } .... }, ..... "VpcConfig": { "Fn::If": [ "CurrentEnvIsLive", { "SecurityGroupIds": [ "sg-xx" ], "SubnetIds": [ "subnet-xxx" ] }, { "SecurityGroupIds": [ "sg-yy" ], "SubnetIds": [ "subnet-yyy" ] } ] },
Are you sure this is related to current topic
This bug is killing us. We use a custom cognito authentication flow (magic links) and we wanted to allow our users to choose to get their magic link via email or sms. We wanted to use ClientMetadata
from Auth.signIn
in order to convey the information {sendLinkViaSms: boolean}
so that our custom lambdas know wether to send an email or a SMS.
The only trigger called with ClientMetadata
on InitiateAuth
is PreAuthentication
(documented here). Our plan was to update a user custom attribute with this information, so that the trigger responsible to send the magic link (CreateAuthChallenger
) could read that info and send the message on the approriate channel.
But with this bug, we have no way of transmitting business logic information from the user to the cognito triggers, seriously limiting our feature development capabilities.
This bug is killing us. We use a custom cognito authentication flow (magic links) and we wanted to allow our users to choose to get their magic link via email or sms. We wanted to use
ClientMetadata
fromAuth.signIn
in order to convey the information{sendLinkViaSms: boolean}
so that our custom lambdas know wether to send an email or a SMS.The only trigger called with
ClientMetadata
onInitiateAuth
isPreAuthentication
(documented here). Our plan was to update a user custom attribute with this information, so that the trigger responsible to send the magic link (CreateAuthChallenger
) could read that info and send the message on the approriate channel.But with this bug, we have no way of transmitting business logic information from the user to the cognito triggers, seriously limiting our feature development capabilities.
@mmeylan we are exactly in the same situation! You've made a very good summary of the situation :heart:. As we're not live in production yet on our side... it's ok-ish. We have alternatives in mind like Auth0 or NextAuth or even Symfony 5.2 incoming magic link.
@elorzafe is it planned at some point to fix it? Is it in any roadmap? Documentation should be at least updated to warn that it's a dead end for every people that try to implement magic links no? Especially since this post has been published more than 1 year ago. The related github repository had some mark of interest (> 100 stars & probably a magnitude of interested people that have not starred it).
All thank you for the feedback in regards to this. As @elorzafe has callout, this issue is not related to Amplify and more so for Amazon Cognito. Amplify is used as a proxy to AWS resources such as Amazon Cognito. We will look to talk to them internally about this however, I do recommend reaching out to Amazon Cognito via their forums.
@sammartinez copy that, so we can close this issue @Spy-Seth. We are agree, this is pure Cognito issue, not Amplify related.
I've found a related thread on Cognito forum, other people that reproduces but not answered. So if you can internally do something :pray: passwordless is a big trend at the moment (as WebAuthn will probably be the next one).
Do you have some updates guys?
I got this from AWS support today (almost 2 years after this issue was open):
Thanks for your patience. I can confirm that the service team is still working on the request to invoke preAuth trigger when custom auth flow is used. I have added your case to the request to better prioritize the development. I am checking if there is a workaround on this.
I see that the preAuth Lambda will be triggered only if PASSWORD_VERIFIER challenge is used as the first challenge in the custom auth flow.
Hit this issue as well.. Would love to see this issue get fixed as it's also impacting my passwordless workflow.
Same here, any updates on when this could be fixed?
Is there any development on this issue?
This bug is killing us. We use a custom cognito authentication flow (magic links) and we wanted to allow our users to choose to get their magic link via email or sms. We wanted to use
ClientMetadata
fromAuth.signIn
in order to convey the information{sendLinkViaSms: boolean}
so that our custom lambdas know wether to send an email or a SMS.The only trigger called with
ClientMetadata
onInitiateAuth
isPreAuthentication
(documented here). Our plan was to update a user custom attribute with this information, so that the trigger responsible to send the magic link (CreateAuthChallenger
) could read that info and send the message on the approriate channel.But with this bug, we have no way of transmitting business logic information from the user to the cognito triggers, seriously limiting our feature development capabilities.
any news on this? :)
any update on it?
I implemented custom challenge mode to add passwordless login with sms-code and wanted to prevent fraud sms sending in case recaptcha is missing (sms is sent in create challenge trigger) . the only trigger that seems to fit this purpose is pre auth since it does have access to metadata that client can send, but this trigger is not called with custom challenge mode...
Hey @mordechai-dror i have the same issue, did you figure out a workaround?
@kelvin-iimmpact The current solution is that the client first goes to dynamodb table, where each user has its own account record, updates there the required metadata, and only after it sends auth request, so the custom challenge lambda can query dynamodb by cognito user sub/username and retrieve the metadata. it means that the init auth process is split into two separate requests, which is not perfect, but at least it works