When I create a new user in Auth0 (username password authentication) a verification email is sent out to the user.
Without verifying the email the user is still able to sign into Auth0. Actually this is what I want in this particular scenario, however, what is the usual flow in this?
I tried searching for documentation on this verification process on Auth0 but could not find any. Plus if I want the user to verify the mail before signing in how do I configure this? Is this documented somewhere?
As you mentioned, email verification is natively supported in Auth0 when using the username/password authentication. The status of the email verification procedure is tracked through the email_verified property available in the user profile.
By default and inline with what you experienced, authentication is not blocked for non-verified users, however, you can quickly achieve this through a rule (Force email verification):
function (user, context, callback) {
if (!user.email_verified) {
return callback(new UnauthorizedError('Please verify your email before logging in.'));
} else {
return callback(null, user, context);
}
}
As noted in the rule page you can also handle this in the application itself by checking the user profile and conditionally reply based on the email verification flag; this will allow you to provide a more customized experience for non-verified users.
Related
Im creating a login for a CMS to a website for a small business using the React javascript framework. Obviously random people can't just register their own details so at present i am attempting to manually create the users (a max of 5 at present) within the cognito console. I have the majority of the authentication workflow established (using just the Auth library from Amplify) with INITIAL forced password reset, forced MFA TOTP authentication and successful access to the CMS on login. However the Forgotten Password functionality despite my best efforts just refuses to work and I believe I've narrowed it down to cognito itself.
Short of trying every damn combination of a user pool and created user to get this to work, I provide the following when creating a user from the cognito console -
1. Username (must be email)
2. Temporary Password
3. No phone or phone verification
4. Email and tick email verification
For the userpool conditions the following is the current working setup (minus the forgotten password functionality)
1. Email Address required for sign in
2. Standard attributes are given name, family name, phone number
3. MFA is required
4. Second factor is Time Based One Time Password
5. Email is selected as the attribute to be verified (which i believe to be a moot point as this is manually done when creating user)
6. No SMS role provided, required or necessary
7. I have verified an email address with SNS and have this entered in the FROM and REPLY-TO fields for email customization and have selected the use of using Amazon SES below these customization fields.
This is the entry point of my Authentication workflow, identifying where in the workflow the user is at and acting accordingly.
await Auth.signIn(email, password)
.then(user => {
setFetching(false);
switch (user.challengeName) {
case "NEW_PASSWORD_REQUIRED":
switchComponent("Verify", user);
break;
case "SMS_MFA":
case "SOFTWARE_TOKEN_MFA":
switchComponent("ConfirmSignIn", user);
break;
case "MFA_SETUP":
switchComponent("MFASetup", user);
break;
default:
history.push({ pathname: "/" });
break;
}
})
Everything works as it should for the most part. MFA workflow displays a nice QR Code for the user to utilize and confirm using their Authenticator of choice, NEW_PASSWORD_REQUIRED is submitted via the following -
const handleSubmit = async event => {
event.preventDefault();
if (noErrors()) {
setFetching(true);
await Auth.completeNewPassword(inputs.user, inputs.newPassword, {
email: inputs.email,
phone_number: inputs.phoneNumber,
given_name: inputs.givenName,
family_name: inputs.familyName
})
.then(() => {
setFetching(false);
switchComponent("MFASetup", inputs.user);
})
.catch(err => onShowDialog(err.message));
setFetching(false);
}
};
From what i can tell, nothing is out of the ordinary here. However any attempts to initialize the forgotten password flow after successfully authenticating past the REQUIRE_PASSWORD_RESET, even from the cognito console and i am presented with "Cannot reset password for the user as their is no registered/verified email or phone number", this is despite enabling the "verified email" when creating the user from the cognito console.
By using the aws command line I can force the verification however this to me is just infuriatingly unintuitive when the enabling of this when creating the user should take effect. Im at my wits end here and I have clients waiting for this software. Any help would be greatly appreciated in this instance. I apologize for any redundant content in this question I just want to make sure I cover everything the first time. Regards.
In AWS Cognito, I want to allow the user to login only after confirming both phone number and email. Is there any way similar to GetUserAttributeVerificationCode API call where I can get the code without requiring the AccessToken from the user ?
I am on similar situation where I want to send verification code through lambda. I tried post authentication lambda trigger to check if we get accesstoken but no luck(which is a good thing from security point of view)
So, unfortunately, there is no AdminGetUserAttributeVerificationCode or any other method that lets you send verification code to a user without access token. The idea behind that seems to be that only the logged in user should be able to send verification code to himself and not to anyone else.
May be this restriction is to prevent anyone(including AWS) to send mass verification codes to public without their consent (spamming).
I'm using ASW Cognito for authenticating users. Cognito has a well-documented flow to handle users who have forgotten their passwords.
How do I handle users who have forgotten their usernames? Is there a built-in flow that lets the user enter their email or phone number, and then receive an email or text with their associated username? I found the ListUser API, which returns all the users in a userpool. I could write a Lambda function that filters through all my users, looking for a match on email or phone number. But this seems like overkill.
Unfortunately, there is no default out of the box workflow of "Forgot Username".
I am implementing similar workflow. We ask user for their registered phone number/email, and we retrieve username based on that number and send it to email/phone according to configuration. If user is configured to use email and phone both, we send SMS to phone if user forget username (which is email id they used during sign up).
One major drawback of this approach is that, we need to provide ListUsers API call access to anonymous user which is a potential security issue but can't seem to find any other way by which we inform user about their login details.
For those, who are looking for the solution, don't give the anonymous user access to ListUser API as suggested in the accepted answer.
There are two ways to implement 'Forgot username flow'.
Enable email as an alias for your Cognito User Pool:
Calling this API causes a message to be sent to the end user with a
confirmation code that is required to change the user's password. For
the Username parameter, you can use the username or user alias. The
method used to send the confirmation code is sent according to the
specified AccountRecoverySetting.
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ForgotPassword.html
The user will be able to reset the password with their email and code delivered to provided email address. If you still want to remind the username, you can use Lambda trigger to generate the password reset email with both username and verification code.
Use the backend (web server or lambda) which will receive the email address as an input to the 'Forgot username flow'. The backend will have permissions to invoke List Users API (https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListUsers.html) and will perform user lookup using the email. You now can go into Forgot Password flow using the retrieved username. Lambda trigger will be used to generate password reset email with username and verification code.
You can protect this API from abuse using WAF and/or captcha.
In this code snippet (firebase doc) they have mentioned do not use user.getUid() to authenticate with your backend server. use FirebaseUser.getToken() instead.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// Name, email address, and profile photo Url
String name = user.getDisplayName();
String email = user.getEmail();
Uri photoUrl = user.getPhotoUrl();
// The user's ID, unique to the Firebase project. Do NOT use this value to
// authenticate with your backend server, if you have one. Use
// FirebaseUser.getToken() instead.
String uid = user.getUid();
}
getUid() // A unique user ID, intended as the user's unique key across all providers.
getToken() // The Firebase authentication token for this session.
My requirement is.
First I will register user with firebase authentication method (Email and password).
I will save String uid = user.getUid(); in my own backend server once registration is successful.
User credit information say user balance is saved in my own backend server as key user.getUid().
User sign-in with Email and password and ask for his balance.
I will get user.getUid() from firebase and match with my records, if match found returns balance to user.
They said getUid() is unique user id but Do NOT use this value to authenticate with your backend server.
Why so? Why can't we use getUid() to authenticate with your backend server??
The uid is a unique identifier for the user. So, while it identifies the user, it does not authenticate them.
A simple corollary is that my Stack Overflow ID is 209103. Knowing that, you can identify me. But to prove to Stack Overflow that you are Frank van Puffelen, requires that you know my credentials.
The ID of a user is quite often exposed in the interface. For example, if you click on my profile, you will see my ID. This is necessary for identifying me. If you would also use that same ID to authenticate, everyone who had seen your profile once could impersonate you on the site. Not a good idea when it comes to security.
Take your requirements as an example, if you using [GET] https://your-domain.com/api/users/$uid/balance to retrieve user's data, then this API is not secured at all, anybody could get other user's data with a random $uid.
As the comment(firebase doc) recommends, FirebaseUser.getToken() will get a JWT token, you should validate the token with firebase Admin SDK in your backend, and that is the data you could trust.
And the method client-side method should update to user.getIdToken() by now.
https://firebase.google.com/docs/auth/admin/verify-id-tokens is the reference for more detail.
We have a web application using SimpleMembership with a confirmation mail being sent upon registration. Now I want the user to automatically get logged in when he or she verifies the account.
I guess the way to go is to get the user associated with the confirmation token and then use:
if (WebSecurity.UserExists(username))
{
FormsAuthentication.SetAuthCookie(username, false);
}
The problem is that there doesn't seem to be any simple way to retrieve the confirmation token. WebSecurity has a function GetUserIdFromPasswordResetToken() but that does not really help.
Here is an article on retrieving the confirmation token in SimpleMembership.
But the intent of retrieving the confirmation token in this article was to resend the email to the user. I would be careful automatically logging the person in after the confirmation process as it may introduce a security vulnerability. This would allow anyone that got a hold of the email with the link to log-in to that account. For security reasons it is best to have the user log-in with their credentials after confirmation. You will see this discussed in the comments for this article.