Как изменить статус пользователя FORCE_CHANGE_PASSWORD?

Используя AWS Cognito, я хочу создать фиктивных пользователей для целей тестирования.

Затем я использую Консоль AWS для создания такого пользователя, но его статус установлен на FORCE_CHANGE_PASSWORD. С этим значением этот пользователь не может быть аутентифицирован.

Есть ли способ изменить этот статус?

ОБНОВЛЕНИЕ То же поведение при создании пользователя из CLI

Ответ 1

Извините, у вас возникли трудности. У нас нет одношагового процесса, где вы можете просто создавать пользователей и аутентифицировать их напрямую. Мы можем изменить это в будущем, например, чтобы позволить администраторам устанавливать пароли, которые могут непосредственно использоваться пользователями. На данный момент, когда вы создаете пользователей либо с помощью AdminCreateUser либо путем регистрации пользователей с помощью приложения, требуются дополнительные шаги: либо вынуждаете пользователей менять пароль при входе в систему, либо пользователи проверяют адрес электронной почты или номер телефона, чтобы изменить статус пользователя на CONFIRMED.

Ответ 2

Я знаю, что это было некоторое время, но подумал, что это может помочь другим людям, которые сталкиваются с этим постом.

Вы можете использовать интерфейс командной строки AWS для изменения пароля пользователя, однако это многоэтапный процесс:


Шаг 1. Получите токен сеанса для нужного пользователя:

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%

Если это возвращает ошибку о Unable to verify secret hash for client, создайте другой клиент приложения без секретного кода и используйте этот идентификатор клиента.

Шаг 2: Если шаг 1 выполнен успешно, он ответит запросом NEW_PASSWORD_REQUIRED, другими параметрами вызова и ключом сеанса пользователя. Затем вы можете запустить вторую команду, чтобы выдать ответ на вызов:

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 ""%

Если вы получили сообщение об ошибке Invalid attributes given, XXX is missing, пропустите отсутствующие атрибуты, используя формат userAttributes.$FIELD_NAME=$VALUE

Приведенная выше команда должна вернуть действительный результат аутентификации и соответствующие токены.


Важное замечание: Чтобы это работало, в пуле пользователей Cognito ДОЛЖЕН быть настроен клиент приложения с функциональностью ADMIN_NO_SRP_AUTH (шаг 5 в этом документе).

Ответ 3

Вы можете изменить этот статус пользователя FORCE_CHANGE_PASSWORD, вызвав respondToAuthChallenge() для этого пользователя:

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
});

После этого в консоли вы увидите, что статус user3 равен CONFIRMED.

Ответ 4

Просто добавьте этот код после onSuccess: function (result) { ... }, в свою функцию входа. Затем ваш пользователь будет иметь статус ПОДТВЕРЖДЕН.

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);
}

Ответ 5

Наконец, это было добавлено в AWSCLI: https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/admin-set-user-password.html

Вы можете изменить пароль пользователя и обновить статус, используя:

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

Перед его использованием может потребоваться обновить интерфейс командной строки AWS с помощью:

pip3 install awscli --upgrade

Ответ 6

не уверен, что вы все еще боретесь с этим, но для создания группы только тестовых пользователей я использовал awscli как таковой:

  1. Используйте подкоманду регистрации из cognito-idp, чтобы создать пользователя
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. Подтвердите пользователя, используя admin-verify-зарегистрироваться
aws cognito-idp admin-confirm-sign-up \
--user-pool-id %aws_user_pools_web_client_id% \
--username %email_address%

Ответ 7

Вы можете решить эту проблему, используя SDK amazon-cognito-identity-js, путем аутентификации с помощью временного пароля после создания учетной записи с помощью cognitoidentityserviceprovider.adminCreateUser() и запускать cognitoUser.completeNewPasswordChallenge() внутри cognitoUser.authenticateUser( ,{newPasswordRequired}) - все внутри функции, которая создает пользователя.

Я использую код ниже внутри AWS lambda для создания учетных записей пользователей Cognito. Я уверен, что его можно оптимизировать, быть терпеливым со мной. Это мой первый пост, и я до сих пор довольно новичок в 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, e.g. email to new user
                    resolve(finalResult);
                })
                .catch(err => {
                    reject(err);
                });
        });
        return anotherPromise;
    })
    .then(() => {
        resolve(finalResult);
    })
    .catch(err => {
        reject({ statusCode: 406, error: err });
    });

Ответ 8

Для Java SDK, предполагая, что ваш клиент Cognito настроен и у вас есть пользователь в состоянии FORCE_CHANGE_PASSWORD, вы можете сделать следующее, чтобы получить вашего пользователя ПОДТВЕРЖДЕНО... и затем выполнить аутентификацию как обычно.

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

Надеюсь, это поможет с этими интеграционными тестами (извините за форматирование)

Ответ 9

Я знаю, что это тот же ответ, но подумал, что это может помочь сообществу разработчиков Go. в основном это инициация запроса NEW_PASSWORD_REQUIRED, получение сеанса и ответ на вызов 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 
}

Здесь юнит тест:

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)

        })

    })
}

Ответ 10

ХОРОШО. Наконец-то у меня есть код, где администратор может создать нового пользователя. Процесс идет так:

  1. Админ создает пользователя
  2. Пользователь получает письмо со своим временным паролем
  3. Пользователь входит в систему и просит изменить свой пароль

Шаг 1 - сложная часть. Вот мой код для создания пользователя в Node JS:

let params = {
  UserPoolId: "@[email protected]",
  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: "@[email protected]",
      Username: username
    }, function(err) {
      if (err) {
        console.log(err, err.stack);
      } else {
        console.log("Success!");
        resolve(data);
      }
    });
  }
});

По сути, вам нужно отправить вторую команду, чтобы заставить письмо считаться проверенным. Пользователю все еще нужно перейти на свою электронную почту, чтобы получить временный пароль (который также проверяет электронную почту). Но без этого второго звонка, который устанавливает электронную почту для проверки, вы не получите право перезвонить, чтобы сбросить их пароль.

Ответ 11

По сути, это тот же ответ, но для .Net С# SDK:

Далее будет сделано полное создание пользователя с желаемым именем пользователя и паролем. Имея следующую модель пользователя:

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

Вы можете создать пользователя и сделать его готовым к использованию, используя:

   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
        });
    }