AWS Cognito用户迁移池触发器不适用于登录流程 [英] AWS cognito user migration pool trigger not working on login flow

查看:62
本文介绍了AWS Cognito用户迁移池触发器不适用于登录流程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用具有cognito执行角色的Lambda函数使用AWS cognito池迁移以下是我的新池应用程序客户端设置

I am using AWS cognito pool migration using Lambda function with cognito execution role Following is my new pool app client setting

AWS文档说

用户迁移身份验证流程用户迁移Lambda触发器允许从旧版用户管理系统轻松迁移用户进入您的用户池.为避免让您的用户重设密码在用户迁移期间,请选择USER_PASSWORD_AUTH身份验证流动.该流程将您的用户密码通过身份验证期间加密的SSL连接.

User migration authentication flow A user migration Lambda trigger allows easy migration of users from a legacy user management system into your user pool. To avoid making your users reset their passwords during user migration, choose the USER_PASSWORD_AUTH authentication flow. This flow sends your users' passwords to the service over an encrypted SSL connection during authentication.

完成所有用户的迁移后,我们建议将流切换到更安全的SRP流.SRP流程不通过网络发送任何密码.

When you have completed migrating all your users, we recommend switching flows to the more secure SRP flow. The SRP flow does not send any passwords over the network.

我已经创建了角色为"AmazonCognitoPowerUser"的lambda函数

I have created lambda function with role "AmazonCognitoPowerUser"

        async function authenticateUser(cognitoISP: CognitoIdentityServiceProvider, username: string, password: string): Promise<User | undefined> {
            console.log(`authenticateUser: user='${username}'`);

            const params: AdminInitiateAuthRequest = {
                AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',
                AuthParameters: {
                    PASSWORD: password,
                    USERNAME: username,
                },
                ClientId: OLD_CLIENT_ID,
                UserPoolId: OLD_USER_POOL_ID,
            };
            const cognitoResponse = await cognitoISP.adminInitiateAuth(params).promise();
            const awsError: AWSError = cognitoResponse as any as AWSError;
            if (awsError.code && awsError.message) {
                console.log(`authenticateUser: error ${JSON.stringify(awsError)}`);
                return undefined;
            }
            console.log(`authenticateUser: found ${JSON.stringify(cognitoResponse)}`);

            return lookupUser(cognitoISP, username);
        }

        async function lookupUser(cognitoISP: CognitoIdentityServiceProvider, username: string): Promise<User | undefined> {
            console.log(`lookupUser: user='${username}'`);
            const params = {
                UserPoolId: OLD_USER_POOL_ID,
                Username: username,
            };
            const cognitoResponse = await cognitoISP.adminGetUser(params).promise();
            const awsError: AWSError = cognitoResponse as any as AWSError;
            if (awsError.code && awsError.message) {
                console.log(`lookupUser: error ${JSON.stringify(awsError)}`);
                return undefined;
            }
            console.log(`lookupUser: found ${JSON.stringify(cognitoResponse)}`);

            const userAttributes = cognitoResponse.UserAttributes ? cognitoResponse.UserAttributes.reduce((acc, entry) => ({
                ...acc,
                [entry.Name]: entry.Value,
            }), {} as {[key: string]: string | undefined}) : {};
            const user: User = {
                userAttributes,
                userName: cognitoResponse.Username,
            };
            console.log(`lookupUser: response ${JSON.stringify(user)}`);
            return user;
        }

        async function onUserMigrationAuthentication(cognitoISP: CognitoIdentityServiceProvider, event: CognitoUserPoolTriggerEvent) {
            // authenticate the user with your existing user directory service
            const user = await authenticateUser(cognitoISP, event.userName!, event.request.password!);
            if (!user) {
                throw new Error('Bad credentials');
            }

            event.response.userAttributes = {
                // old_username: user.userName,
                // 'custom:tenant': user.userAttributes['custom:tenant'],
                email: user.userAttributes.email!,
                email_verified: 'true',
                preferred_username: user.userAttributes.preferred_username!,
            };
            event.response.finalUserStatus = 'CONFIRMED';
            event.response.messageAction = 'SUPPRESS';

            console.log(`Authentication - response: ${JSON.stringify(event.response)}`);
            return event;
        }

        async function onUserMigrationForgotPassword(cognitoISP: CognitoIdentityServiceProvider, event: CognitoUserPoolTriggerEvent) {
            // Lookup the user in your existing user directory service
            const user = await lookupUser(cognitoISP, event.userName!);
            if (!user) {
                throw new Error('Bad credentials');
            }

            event.response.userAttributes = {
                // old_username: user.userName,
                // 'custom:tenant': user.userAttributes['custom:tenant'],
                email: user.userAttributes.email!,
                email_verified: 'true',
                preferred_username: user.userAttributes.preferred_username!,
            };
            event.response.messageAction = 'SUPPRESS';

            console.log(`Forgot password - response: ${JSON.stringify(event.response)}`);

            return event;
        }

        export const handler = async (event: CognitoUserPoolTriggerEvent, context: Context): Promise<CognitoUserPoolTriggerEvent> => {
            const options: CognitoIdentityServiceProvider.Types.ClientConfiguration = {
                region: OLD_USER_POOL_REGION,
            };
            if (OLD_ROLE_ARN) {
                options.credentials = new ChainableTemporaryCredentials({
                    params: {
                        ExternalId: OLD_EXTERNAL_ID,
                        RoleArn: OLD_ROLE_ARN,
                        RoleSessionName: context.awsRequestId,
                    },
                });
            }
            const cognitoIdentityServiceProvider = new CognitoIdentityServiceProvider(options);

            switch (event.triggerSource) {
                case 'UserMigration_Authentication':
                    return onUserMigrationAuthentication(cognitoIdentityServiceProvider, event);
                case 'UserMigration_ForgotPassword':
                    return onUserMigrationForgotPassword(cognitoIdentityServiceProvider, event);
                default:
                    throw new Error(`Bad triggerSource ${event.triggerSource}`);
            }
        }

并将触发器添加到新池中,

and added trigger into new pool,

经过多次尝试,Lambda触发器无法用于登录,始终会出错.

  {__type: "NotAuthorizedException", message: "Incorrect username or password."}
       message: "Incorrect username or password."
     __type: "NotAuthorizedException"

如果使用重置密码用户迁移到新池后使用忘记密码"流,则可以正常工作

已更新:

使用以下json直接在lambda上运行测试时

When directly run test on lambda using following json

  {
   "version": "1",
   "triggerSource": "UserMigration_Authentication",
   "region": "ap-south-1",
   "userPoolId": "ap-XXXXXXXXX2",
   "userName": "vaquar.test@gmail.com",
   "callerContext": {
   "awsSdkVersion": "aws-sdk-unknown-unknown",
   "clientId": "1XXXXXXXXXXXXXXXXXXfgk"
   },
   "request": {
   "password": "vkhan",
   "validationData": null,
   "userAttributes": null
    },
   "response": {
    "userAttributes": null,
    "forceAliasCreation": null,
    "finalUserStatus": null,
    "messageAction": null,
    "desiredDeliveryMediums": null
    }
  }

然后得到以下响应,并且用户迁移到新池中,这意味着我们在登录期间触发了问题.

Then getting following response and user migrated into new pool means we have issue in trigger during login.

 INFO   Authentication - response: {"userAttributes":{"email":"vaquar.test@gmail.com","email_verified":"true"},"forceAliasCreation":null,"finalUserStatus":"CONFIRMED","messageAction":"SUPPRESS","desiredDeliveryMediums":null}

推荐答案

请验证您的应用程序使用的是OAUTH流USER_PASSWORD,而不是默认的USER_SRP_AUTH.

Please verify that your application is using OAUTH flow USER_PASSWORD instead of the default USER_SRP_AUTH.

供参考:链接

这篇关于AWS Cognito用户迁移池触发器不适用于登录流程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆