如何更改用户状态FORCE_CHANGE_PASSWORD?

时间:2016-10-27 14:17:07

标签: amazon-web-services aws-cli amazon-cognito

使用AWS Cognito,我想创建虚拟用户以进行测试。

然后我使用 AWS控制台创建此类用户,但用户将状态设置为FORCE_CHANGE_PASSWORD。使用该值,无法对此用户进行身份验证。

有没有办法改变这种状态?

UPDATE 从CLI

创建用户时的行为相同

13 个答案:

答案 0 :(得分:103)

我知道已经有一段时间了,但我认为这可能有助于遇到这篇文章的其他人。

您可以使用AWS CLI更改用户密码,但这是一个多步骤过程:

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

如果返回“无法验证客户端的秘密哈希”错误,请创建另一个没有密钥的应用客户端并使用该客户端ID。

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

如果您收到有关“无效属性,XXX缺失”的错误,请使用userAttributes格式传递缺少的属性。$ FIELD_NAME = $ VALUE

上述命令应返回有效的身份验证结果和相应的令牌。

为此,Cognito用户池必须具有配置了ADMIN_NO_SRP_AUTH功能的App客户端。 (注意步骤5 http://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html

答案 1 :(得分:16)

您可以通过在用户上调用 respondToAuthChallenge()来更改该用户状态FORCE_CHANGE_PASSWORD:

var params = {
  ChallengeName: 'NEW_PASSWORD_REQUIRED', 
  ClientId: 'your_own3j63rs8j16bxxxsto25db00obh',
  ChallengeResponses: {
    USERNAME: 'user3',
    NEW_PASSWORD: 'changed12345'
  },
  Session: 'xxxxxxxxxxZDMcRu-5u019i_gAcX5lw1biFnKLtfPrO2eZ-nenOLrr5xaHv-ul_-nGsOulyNG12H85GJ2UGiCGtfe-BdwTmQ-BMUnd2Twr9El45xgpGKWDrYcp11J4J9kZN71ZczynizRJ7oa5a_j2AiBYukzhd_YzPWGscrFu98qqn_JoiLsJ7w9v_C_Zpw6-ixCs09suYQKZ3YlWNFmMpC2nSiKrXUA8ybQkdj6vIO68d-vtYq0mVHt410v2TBtK4czOAh5MieO55kgvGHCxvEusQOTeFYh4Mjh1bwcHWRvSV6mVIrVSm4FnRs0u26vUDq79CgkuycRl2iOoqxc1abcaANKmEB45r2oPnmPZIhVqNO5eHe6fpac7s3pHwLKvNOv7EaQkjyY9Vb5gINmSjXBjBl3O3aqQ7KXyueuHHSLrfchP64SwuNQZSfL1Vis0ap5JtSat3udslzUBiU8FEhmJNwPX08QyIm4DqviTLp6lDqH5pH6BuvO9OUHPrEcDzufOx1a76pld-9f-NGfactCUZC0elQcAiGSqbwfiRYHn7TDHuX1WKf9L9E6GvhJhB154SxxhXsLm3Yv9DhWhOlVbhdbzR2Bq4dqJRDOPY2wengFX6v36TLlYZTHbGEc_PbSlx8Ru80avxehAmUNtNqDYjGbXq0vBWaEiJmkr1isF7XsCvrmZb6tHY'
};

cognitoidentityserviceprovider.respondToAuthChallenge(params, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(data);           // successful response
});

在此之后,您将在控制台中看到user3状态为CONFIRMED

答案 2 :(得分:14)

只需在您的登录功能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);
}

答案 3 :(得分:11)

抱歉,您遇到了困难。我们没有一步到位的流程,您只需创建用户并直接对其进行身份验证即可。我们将来可能会对此进行更改,例如允许管理员设置用户可直接使用的密码。目前,当您使用AdminCreateUser创建用户或使用该应用注册用户时,需要执行额外的步骤,要么强制用户在登录时更改密码,要么让用户验证电子邮件或电话号码以更改状态用户的CONFIRMED

答案 4 :(得分:5)

如果您试图从控制台以管理员身份更改状态。创建用户后,请按照以下步骤操作。

  1. 在Cognito转到->“管理用户池”->
  2. 转到“应用集成”部分下的“应用客户端设置”。
  3. 检查以下项目 i)Cognito用户池ii)授权代码授予iii)隐式授予iv)电话v)电子邮件vi)openid vii)aws.cognito.signin.user.admin viii)个人资料
  4. 输入您的应用程序的回调URL。如果不确定,请输入例如:https://google.com,然后再将其更改为实际的回调URL
  5. 点击保存更改。
  6. 保存更改后,请点击链接“启动托管的用户界面”
  7. 输入新创建的用户的凭据
  8. 使用新凭据重置密码,并将其共享给用户

step 2

step 3 4 5 6

step 7

step 8

答案 5 :(得分:4)

您可以使用amazon-cognito-identity-js SDK解决此问题,方法是使用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 });
    });

答案 6 :(得分:3)

对于Java SDK,假设您的Cognito客户端已设置且您的用户处于FORCE_CHANGE_PASSWORD状态,您可以执行以下操作以使您的用户确认...然后正常验证。

# detect columns with 0
col_has_0 = colSums(y == 0) >= 1
# remove them
y = y[, !col_has_0]

希望它有助于这些集成测试(抱歉格式化)

答案 7 :(得分:1)

行。我终于拥有管理员可以创建新用户的代码。过程如下:

  1. 管理员创建用户
  2. 用户收到一封包含临时密码的电子邮件
  3. 用户登录并被要求更改密码
  4. 第1步是困难的部分。这是我在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);
          }
        });
      }
    });
    

    基本上,您需要发送第二个命令以强制将电子邮件视为已验证。用户仍然需要转到他们的电子邮件以获取临时密码(也验证电子邮件)。但如果没有将电子邮件设置为已验证的第二个电话,您将无法获得正确的回拨以重置其密码。

答案 8 :(得分:1)

不确定您是否仍在与之抗争,但仅创建了一组测试用户,我就这样使用了awscli

  1. 使用cognito-idp中的signup-up子命令创建用户
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-confirm-sign-up确认用户
aws cognito-idp admin-confirm-sign-up \
--user-pool-id %aws_user_pools_web_client_id% \
--username %email_address%

答案 9 :(得分:1)

我知道答案是相同的,但是认为它可能对Go开发人员社区有所帮助。基本上是发起身份验证请求,获取会话并响应质询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)

此内容最终已添加到AWSCLI:https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/admin-set-user-password.html

您可以使用以下方法更改用户密码和更新状态:

ion-input

在使用此功能之前,您可能需要使用以下命令更新AWS CLI:

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

答案 11 :(得分:0)

基本上,这是相同的答案,但对于.Net C#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
        });
    }

答案 12 :(得分:0)

我遇到过很多次同样的情况。因此,在 golang 中编写了小型 CLI,以完全以用户身份进行身份验证(用于进一步测试目的),或者只是以管理方式重置通行证。

那么你运行的所有命令都是

$ > go-cognito-authy --profile cloudy -region eu-central-1 admin reset-pass --username rafpe --pass-new 'Password.0ne2!' --clientID 2jxxxiuui123 --userPoolID  eu-central-1_CWNnTiR0j --session "bCqSkLeoJR_ys...."

解决方案可在 github https://github.com/RafPe/go-cognito-authy/tree/master