How to change user status FORCE_CHANGE_PASSWORD?

Using AWS Cognito, I want to create dummy users for testing purposes.

Then I use the AWS Console to create such a user, but his status is set to FORCE_CHANGE_PASSWORD . With this value, this user cannot be authenticated.

Is there any way to change this status?

UPDATE The same behavior when creating a user from the CLI

+61
source share
11 answers

Sorry, you are having difficulty. We do not have a one-step process where you can simply create users and authenticate them directly. We can change this in the future, for example, to allow administrators to set passwords that can be directly used by users. At the moment, when you create users either using AdminCreateUser or by registering users using the application, additional steps are required: either force users to change the password at logon, or users check the email address or phone number to change the user status to CONFIRMED .

+12
source

I know that it has been a while, but thought it could help other people who come across this post.

You can use the AWS command line interface to change the user password, however this is a multi-step process:


Step 1. Get the session token for the right user:

 aws cognito-idp admin-initiate-auth --user-pool-id %USER POOL ID% --client-id %APP CLIENT ID% --auth-flow ADMIN_NO_SRP_AUTH --auth-parameters USERNAME=%USERS USERNAME%,PASSWORD=%USERS CURRENT PASSWORD% 

If this returns an error about Unable to verify secret hash for client , create another application client without a secret code and use this client identifier.

Step 2: If step 1 is successful, it will respond with a NEW_PASSWORD_REQUIRED request, other call parameters, and a user session key. Then you can run the second command to answer the call:

 aws cognito-idp admin-respond-to-auth-challenge --user-pool-id %USER POOL ID% --client-id %CLIENT ID% --challenge-name NEW_PASSWORD_REQUIRED --challenge-responses NEW_PASSWORD=%DESIRED PASSWORD%,USERNAME=%USERS USERNAME% --session %SESSION KEY FROM PREVIOUS COMMAND with ""% 

If you receive the error message Invalid attributes given, XXX is missing , skip the missing attributes using the userAttributes.$FIELD_NAME=$VALUE format userAttributes.$FIELD_NAME=$VALUE

The above command should return a valid authentication result and corresponding tokens.


Important Note: For this to work, the application client with ADMIN_NO_SRP_AUTH functionality MUST be configured in the Cognito user pool (step 5 in this document ).

+120
source

You can change this status of the user FORCE_CHANGE_PASSWORD by calling respondToAuthChallenge() for this user:

 var params = { ChallengeName: 'NEW_PASSWORD_REQUIRED', ClientId: 'your_own3j6...0obh', ChallengeResponses: { USERNAME: 'user3', NEW_PASSWORD: 'changed12345' }, Session: 'xxxxxxxxxxZDMcRu-5u...sCvrmZb6tHY' }; cognitoidentityserviceprovider.respondToAuthChallenge(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response }); 

After that, in the console you will see that the status of user3 is CONFIRMED .

+18
source

Just add this code after onSuccess: function (result) { ... }, in your login function. Then your user will have the CONFIRMED status.

 newPasswordRequired: function(userAttributes, requiredAttributes) { // User was signed up by an admin and must provide new // password and required attributes, if any, to complete // authentication. // the api doesn't accept this field back delete userAttributes.email_verified; // unsure about this field, but I don't send this back delete userAttributes.phone_number_verified; // Get these details and call cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this); } 
+17
source

Finally, it was added to AWSCLI: https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/admin-set-user-password.html

You can change the user password and update the status using:

aws cognito-idp admin-set-user-password --user-pool-id <your user pool id> --username user1 --password password --permanent

Before using it, you may need to update your AWS command-line interface with:

pip3 install awscli --upgrade

+8
source

not sure if you are still struggling with this, but to create a group of test users only, I used awscli as such:

  1. Use the registration subcommand from cognito-idp to create a user
 aws cognito-idp sign-up \ --region %aws_project_region% \ --client-id %aws_user_pools_web_client_id% \ --username %email_address% \ --password %password% \ --user-attributes Name=email,Value=%email_address% 
  1. Confirm user using admin-verify-register
 aws cognito-idp admin-confirm-sign-up \ --user-pool-id %aws_user_pools_web_client_id% \ --username %email_address% 
+6
source

You can solve this problem using the amazon-cognito-identity-js SDK by authenticating with a temporary password after creating an account with cognitoidentityserviceprovider.adminCreateUser() and running cognitoUser.completeNewPasswordChallenge() inside cognitoUser.authenticateUser( ,{newPasswordRequired}) - everything inside the function that creates the user.

I am using the code below inside AWS lambda to create Cognito user accounts. I am sure that it can be optimized, be patient with me. This is my first post, and I'm still pretty new to JavaScript.

 var AWS = require("aws-sdk"); var AWSCognito = require("amazon-cognito-identity-js"); var params = { UserPoolId: your_poolId, Username: your_username, DesiredDeliveryMediums: ["EMAIL"], ForceAliasCreation: false, MessageAction: "SUPPRESS", TemporaryPassword: your_temporaryPassword, UserAttributes: [ { Name: "given_name", Value: your_given_name }, { Name: "email", Value: your_email }, { Name: "phone_number", Value: your_phone_number }, { Name: "email_verified", Value: "true" } ] }; var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider(); let promise = new Promise((resolve, reject) => { cognitoidentityserviceprovider.adminCreateUser(params, function(err, data) { if (err) { reject(err); } else { resolve(data); } }); }); promise .then(data => { // login as new user and completeNewPasswordChallenge var anotherPromise = new Promise((resolve, reject) => { var authenticationDetails = new AWSCognito.AuthenticationDetails({ Username: your_username, Password: your_temporaryPassword }); var poolData = { UserPoolId: your_poolId, ClientId: your_clientId }; var userPool = new AWSCognito.CognitoUserPool(poolData); var userData = { Username: your_username, Pool: userPool }; var cognitoUser = new AWSCognito.CognitoUser(userData); let finalPromise = new Promise((resolve, reject) => { cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function(authResult) { cognitoUser.getSession(function(err) { if (err) { } else { cognitoUser.getUserAttributes(function( err, attResult ) { if (err) { } else { resolve(authResult); } }); } }); }, onFailure: function(err) { reject(err); }, newPasswordRequired(userAttributes, []) { delete userAttributes.email_verified; cognitoUser.completeNewPasswordChallenge( your_newPoassword, userAttributes, this ); } }); }); finalPromise .then(finalResult => { // signout cognitoUser.signOut(); // further action, eg email to new user resolve(finalResult); }) .catch(err => { reject(err); }); }); return anotherPromise; }) .then(() => { resolve(finalResult); }) .catch(err => { reject({ statusCode: 406, error: err }); }); 
+4
source

For the Java SDK, assuming your Cognito client is configured and you have a user in the FORCE_CHANGE_PASSWORD state, you can do the following to get your user CONFIRMED ... and then authenticate as usual.

 AdminCreateUserResult createUserResult = COGNITO_CLIENT.adminCreateUser(createUserRequest()); AdminInitiateAuthResult authResult = COGNITO_CLIENT.adminInitiateAuth(authUserRequest()); Map<String,String> challengeResponses = new HashMap<>(); challengeResponses.put("USERNAME", USERNAME); challengeResponses.put("NEW_PASSWORD", PASSWORD); RespondToAuthChallengeRequest respondToAuthChallengeRequest = new RespondToAuthChallengeRequest() .withChallengeName("NEW_PASSWORD_REQUIRED") .withClientId(CLIENT_ID) .withChallengeResponses(challengeResponses) .withSession(authResult.getSession()); COGNITO_CLIENT.respondToAuthChallenge(respondToAuthChallengeRequest); 

Hope this helps with these integration tests (sorry for formatting)

+4
source

I know this is the same answer, but thought it might help the Go developer community. basically it is initiating a NEW_PASSWORD_REQUIRED request, receiving a session and answering a NEW_PASSWORD_REQUIRED

 func sessionWithDefaultRegion(region string) *session.Session { sess := Session.Copy() if v := aws.StringValue(sess.Config.Region); len(v) == 0 { sess.Config.Region = aws.String(region) } return sess } func (c *CognitoAppClient) ChangePassword(userName, currentPassword, newPassword string) error { sess := sessionWithDefaultRegion(c.Region) svc := cognitoidentityprovider.New(sess) auth, err := svc.AdminInitiateAuth(&cognitoidentityprovider.AdminInitiateAuthInput{ UserPoolId:aws.String(c.UserPoolID), ClientId:aws.String(c.ClientID), AuthFlow:aws.String("ADMIN_NO_SRP_AUTH"), AuthParameters: map[string]*string{ "USERNAME": aws.String(userName), "PASSWORD": aws.String(currentPassword), }, }) if err != nil { return err } request := &cognitoidentityprovider.AdminRespondToAuthChallengeInput{ ChallengeName: aws.String("NEW_PASSWORD_REQUIRED"), ClientId:aws.String(c.ClientID), UserPoolId: aws.String(c.UserPoolID), ChallengeResponses:map[string]*string{ "USERNAME":aws.String(userName), "NEW_PASSWORD": aws.String(newPassword), }, Session:auth.Session, } _, err = svc.AdminRespondToAuthChallenge(request) return err } 

Here's the unit test:

 import ( "fmt" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" . "github.com/smartystreets/goconvey/convey" "testing" ) func TestCognitoAppClient_ChangePassword(t *testing.T) { Convey("Testing ChangePassword!", t, func() { err := client.ChangePassword("user_name_here", "current_pass", "new_pass") Convey("Testing ChangePassword Results!", func() { So(err, ShouldBeNil) }) }) } 
+2
source

WELL. Finally, I have a code where the administrator can create a new user. The process goes like this:

  1. Admin creates a user
  2. The user receives an email with his temporary password
  3. User logs in and asks to change their password

Step 1 is the hard part. Here is my code to create a user in Node JS:

 let params = { UserPoolId: "@ cognito_pool_id@ ", Username: username, DesiredDeliveryMediums: ["EMAIL"], ForceAliasCreation: false, UserAttributes: [ { Name: "given_name", Value: firstName }, { Name: "family_name", Value: lastName}, { Name: "name", Value: firstName + " " + lastName}, { Name: "email", Value: email}, { Name: "custom:title", Value: title}, { Name: "custom:company", Value: company + ""} ], }; let cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider(); cognitoIdentityServiceProvider.adminCreateUser(params, function(error, data) { if (error) { console.log("Error adding user to cognito: " + error, error.stack); reject(error); } else { // Uncomment for interesting but verbose logging... //console.log("Received back from cognito: " + CommonUtils.stringify(data)); cognitoIdentityServiceProvider.adminUpdateUserAttributes({ UserAttributes: [{ Name: "email_verified", Value: "true" }], UserPoolId: "@ cognito_pool_id@ ", Username: username }, function(err) { if (err) { console.log(err, err.stack); } else { console.log("Success!"); resolve(data); } }); } }); 

Essentially, you need to send a second command to make the email be considered verified. The user still needs to go to his email in order to get a temporary password (which also checks email). But without this second call, which sets up an email for verification, you will not receive the right to call back to reset their password.

+1
source

Essentially, this is the same answer, but for .Net C # SDK:

Next, the complete creation of the user with the desired username and password will be done. Having the following user model:

 public class User { public string Username { get; set; } public string Password { get; set; } } 

You can create a user and make him ready to use using:

  public void AddUser(User user) { var tempPassword = "ANY"; var request = new AdminCreateUserRequest() { Username = user.Username, UserPoolId = "MyuserPoolId", TemporaryPassword = tempPassword }; var result = _cognitoClient.AdminCreateUserAsync(request).Result; var authResponse = _cognitoClient.AdminInitiateAuthAsync(new AdminInitiateAuthRequest() { UserPoolId = "MyuserPoolId", ClientId = "MyClientId", AuthFlow = AuthFlowType.ADMIN_NO_SRP_AUTH, AuthParameters = new Dictionary<string, string>() { {"USERNAME",user.Username }, {"PASSWORD", tempPassword} } }).Result; _cognitoClient.RespondToAuthChallengeAsync(new RespondToAuthChallengeRequest() { ClientId = "MyClientId", ChallengeName = ChallengeNameType.NEW_PASSWORD_REQUIRED, ChallengeResponses = new Dictionary<string, string>() { {"USERNAME",user.Username }, {"NEW_PASSWORD",user.Password } }, Session = authResponse.Session }); } 
+1
source

Source: https://habr.com/ru/post/1200252/


All Articles