amazon web services - ¿Cómo cambiar el estado del usuario FORCE_CHANGE_PASSWORD?
amazon-web-services aws-cli (11)
Con AWS Cognito, quiero crear usuarios ficticios con fines de prueba.
Luego uso la
consola de AWS
para crear dicho usuario, pero el usuario tiene su
estado
establecido en
FORCE_CHANGE_PASSWORD
.
Con ese valor, este usuario no puede ser autenticado.
¿Hay alguna manera de cambiar este estado?
ACTUALIZAR El mismo comportamiento al crear un usuario desde la CLI
Básicamente esta es la misma respuesta, pero para .Net C # SDK:
Lo siguiente hará una creación de usuario administrador completa con el nombre de usuario y contraseña deseados. Tener el siguiente modelo de usuario:
public class User
{
public string Username { get; set; }
public string Password { get; set; }
}
Puede crear un usuario y prepararlo para usar con:
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
});
}
Esto finalmente se ha agregado a AWSCLI: https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/admin-set-user-password.html
Puede cambiar la contraseña de un usuario y actualizar el estado utilizando:
aws cognito-idp admin-set-user-password --user-pool-id <your user pool id> --username user1 --password password --permanent
Antes de usar esto, es posible que deba actualizar su AWS CLI usando:
pip3 install awscli --upgrade
Lo siento, estás teniendo dificultades.
No tenemos un proceso de un solo paso en el que pueda crear usuarios y autenticarlos directamente.
Podríamos cambiar esto en el futuro para permitir que los administradores establezcan contraseñas que los usuarios puedan usar directamente.
Por ahora, cuando crea usuarios usando
AdminCreateUser
o registrando usuarios con la aplicación, se requieren pasos adicionales, ya sea forzando a los usuarios a cambiar la contraseña al iniciar sesión o haciendo que los usuarios verifiquen el correo electrónico o el número de teléfono para cambiar el estado del usuario a
CONFIRMED
No estoy seguro si todavía está luchando con esto, pero para crear un grupo de usuarios de prueba solamente, utilicé el
awscli
como tal:
- Use el subcomando de registro de cognito-idp para crear el usuario
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%
- Confirme al usuario usando admin-confirm-sign-up
aws cognito-idp admin-confirm-sign-up /
--user-pool-id %aws_user_pools_web_client_id% /
--username %email_address%
OKAY. Finalmente tengo un código donde un administrador puede crear un nuevo usuario. El proceso es así:
- El administrador crea al usuario
- El usuario recibe un correo electrónico con su contraseña temporal
- El usuario inicia sesión y se le pide que cambie su contraseña
El paso 1 es la parte difícil. Aquí está mi código para crear un usuario en el Nodo 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);
}
});
}
});
Básicamente, debe enviar un segundo comando para forzar que el correo electrónico se considere verificado. El usuario aún necesita ir a su correo electrónico para obtener la contraseña temporal (que también verifica el correo electrónico). Pero sin esa segunda llamada que configura el correo electrónico como verificado, no recibirá la llamada correcta para restablecer su contraseña.
Para Java SDK, suponiendo que su cliente Cognito esté configurado y tenga a su usuario en el estado FORCE_CHANGE_PASSWORD, puede hacer lo siguiente para CONFIRMAR a su usuario ... y luego autenticarlo de manera normal.
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);
Espero que ayude con esas pruebas de integración (perdón por el formato)
Puede cambiar el estado de ese usuario FORCE_CHANGE_PASSWORD llamando a respondToAuthChallenge () en el usuario de esta manera:
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
});
Después de esto, verá en la consola que el estado del usuario3 está CONFIRMADO
Puede resolver esto usando el SDK de amazon-cognito-identity-js autenticándose con la contraseña temporal después de la creación de la cuenta con
cognitoidentityserviceprovider.adminCreateUser()
y ejecutando
cognitoUser.completeNewPasswordChallenge()
dentro de
cognitoUser.authenticateUser( ,{newPasswordRequired})
- dentro de la función que crea tu usuario.
Estoy usando el siguiente código dentro de AWS lambda para crear cuentas de usuario de Cognito habilitadas. Estoy seguro de que se puede optimizar, tenga paciencia conmigo. Esta es mi primera publicación, y todavía soy bastante nuevo en 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 });
});
Sé que es la misma respuesta, pero pensé que podría ayudar a la comunidad de desarrolladores de
Go
.
básicamente está iniciando una solicitud de autenticación, obtenga la sesión y responda al desafío
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
}
Aquí hay una prueba unitaria:
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)
})
})
}
Sé que ha pasado un tiempo, pero pensé que esto podría ayudar a otras personas que se encuentran con esta publicación.
Puede usar la CLI de AWS para cambiar la contraseña de los usuarios, sin embargo, es un proceso de varios pasos:
Paso 1:
Obtenga un token de sesión para el usuario deseado:
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%
Si esto devuelve un error sobre "No se puede verificar el hash secreto para el cliente", cree otro cliente de aplicación sin un secreto y use esa ID de cliente.
Paso 2:
Si el paso 1 es exitoso, responderá con el desafío "NEW_PASSWORD_REQUIRED", otros parámetros del desafío y la clave de sesión de los usuarios.
Luego, puede ejecutar el segundo comando para emitir la respuesta de desafío:
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 ""%
Si recibe un error acerca de "Atributos no válidos dados, XXX falta", pase los atributos faltantes usando el formato userAttributes. $ FIELD_NAME = $ VALUE
El comando anterior debe devolver un resultado de autenticación válido y los tokens apropiados.
Para que esto funcione, el grupo de usuarios de Cognito DEBE tener un cliente de aplicación configurado con la funcionalidad ADMIN_NO_SRP_AUTH. (observe el paso 5 http://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html )
Simplemente agregue este código después de su
onSuccess: function (result) { ... },
dentro de su función de inicio de sesión.
Su usuario tendrá entonces el estado
CONFIRMADO
.
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);
}