programing

사용자 상태 FORCE_CHANGE_PASSWORD를 변경하는 방법은 무엇입니까?

nasanasas 2020. 11. 29. 11:46
반응형

사용자 상태 FORCE_CHANGE_PASSWORD를 변경하는 방법은 무엇입니까?


AWS Cognito를 사용하여 테스트 목적으로 더미 사용자를 만들고 싶습니다.

그런 다음 AWS 콘솔 을 사용하여 이러한 사용자를 생성하지만 사용자의 상태는로 설정됩니다 FORCE_CHANGE_PASSWORD. 이 값을 사용하면이 사용자를 인증 할 수 없습니다.

이 상태를 변경할 수있는 방법이 있습니까?

UPDATE CLI에서 사용자 생성시 동일한 동작


불편을 드려 죄송합니다. 사용자를 생성하고 직접 인증 할 수있는 1 단계 프로세스가 없습니다. 관리자가 사용자가 직접 사용할 수있는 암호를 설정할 수 있도록 향후이를 변경할 수 있습니다. 현재로서는 AdminCreateUser앱을 사용 하거나 사용자를 등록하여 사용자를 생성 할 때 사용자 가 로그인 할 때 비밀번호를 변경하도록하거나 사용자가 이메일 또는 전화 번호를 확인하여 사용자 상태를로 변경하도록하는 추가 단계가 필요합니다 CONFIRMED.


오랜만이라는 것을 알고 있지만 이것이이 게시물을 보는 다른 사람들에게 도움이 될 것이라고 생각했습니다.

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%

오류에 대한이 반환하는 경우 Unable to verify secret hash for client, 비밀 않고 다른 응용 프로그램 클라이언트를 생성 하고 클라이언트 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 ""%

Invalid attributes given, XXX is missing형식을 사용하여 누락 된 속성 전달에 대한 오류가 발생하는 경우userAttributes.$FIELD_NAME=$VALUE

위의 명령은 유효한 인증 결과와 적절한 토큰을 반환해야합니다.


중요 : 이 기능이 작동하려면 Cognito 사용자 풀 기능이 구성된 앱 클라이언트 가 있어야 ADMIN_NO_SRP_AUTH합니다 ( 이 문서의 5 단계 ).


다음 과 같이 사용자 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.


onSuccess: function (result) { ... },로그인 기능 내 에서이 코드를 추가하십시오 . 그러면 사용자는 CONFIRMED 상태가됩니다 .

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

이것은 마침내 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 CLI를 업데이트해야 할 수 있습니다.

pip3 install awscli --upgrade


여전히 이것으로 싸우고 있는지 확실하지 않지만 테스트 사용자를 만들기 위해서만 다음 awscli과 같이 사용했습니다 .

  1. cognito-idp에서 sign-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%

당신은 아마존 - cognito 정체성-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 });
    });

Java SDK의 경우 Cognito 클라이언트가 설정되어 있고 사용자가 FORCE_CHANGE_PASSWORD 상태에 있다고 가정하면 다음을 수행하여 사용자를 CONFIRMED ...를 얻은 다음 정상적으로 인증 할 수 있습니다.

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

통합 테스트에 도움이되기를 바랍니다 (포맷에 대해 죄송합니다).


같은 대답이지만 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)

        })

    })
}

확인. 마침내 관리자가 새 사용자를 만들 수있는 코드가 있습니다. 프로세스는 다음과 같습니다.

  1. 관리자가 사용자를 만듭니다.
  2. 사용자가 임시 비밀번호가 포함 된 이메일을받습니다.
  3. 사용자가 로그인하고 비밀번호를 변경하라는 메시지가 표시됨

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

기본적으로 이메일이 확인 된 것으로 간주되도록 두 번째 명령을 보내야합니다. 사용자는 이메일로 이동하여 임시 비밀번호 (이메일도 확인)를 받아야합니다. 그러나 이메일을 확인하도록 설정하는 두 번째 전화가 없으면 비밀번호를 재설정 할 수있는 올바른 전화를받을 수 없습니다.


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

The following will make a full admin user creation with desired username and password. 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 it 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
        });
    }

참고URL : https://stackoverflow.com/questions/40287012/how-to-change-user-status-force-change-password

반응형