多租户Google Identity Platform中TOTP MFA注册失败求助
在Google Identity Platform多租户模式下,已通过API确认租户已启用TOTP:
curl -X GET "https://identitytoolkit.googleapis.com/v2/projects/xxx/tenants/xxx" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -H "X-Goog-User-Project: xxx"
返回的租户配置显示TOTP已启用:
{ "name": "projects/xxx/tenants/xxx", "displayName": "xxx", "allowPasswordSignup": true, "enableEmailLinkSignin": true, "hashConfig": { "algorithm": "SCRYPT", "signerKey": "xxx", "saltSeparator": "xxx", "rounds": 8, "memoryCost": 14 }, "mfaConfig": { "providerConfigs": [ { "totpProviderConfig": { "adjacentIntervals": 5 }, "state": "ENABLED" } ] }, "inheritance": {} }
但调用accounts:update注册TOTP时收到400错误:
请求地址:POST https://identitytoolkit.googleapis.com/v1/accounts:update
请求体:
{ "tenantId": "xxx", "targetProjectId": "xxx", "mfa": { "enrollments": [ { "displayName": "My TOTP", "mfaEnrollmentId": "totp", "totpInfo": {} } ] }, "localId": "xxx" }
响应结果:
{ "error": { "code": 400, "message": "UNSUPPORTED_SECOND_FACTOR : attempting to add a new TOTP enrollment", "errors": [ { "message": "UNSUPPORTED_SECOND_FACTOR : attempting to add a new TOTP enrollment", "domain": "global", "reason": "invalid" } ] } }
使用Golang Firebase v4 Admin SDK操作也得到相同结果,且控制台UI中仅支持SMS MFA,无TOTP选项。
1. 修正TOTP注册流程(核心问题)
TOTP注册不能直接通过accounts:update添加 enrollment,必须遵循生成密钥→验证验证码→完成注册的三步流程:
步骤1:生成TOTP密钥
调用accounts:generateTotpSecret端点生成临时密钥和注册凭证:
请求地址:POST https://identitytoolkit.googleapis.com/v1/accounts:generateTotpSecret
请求体:
{ "localId": "xxx", "tenantId": "xxx", "targetProjectId": "xxx", "displayName": "My TOTP" }
响应会返回totpSecret、tempEnrollmentId、qrCodeUri、mfaPendingCredential等信息,保存这些值用于后续步骤。
步骤2:用户验证TOTP
让用户使用TOTP应用(如Google Authenticator)扫描qrCodeUri,生成6位验证码。
步骤3:完成TOTP注册
调用accounts:update提交验证信息,完成注册:
请求体:
{ "localId": "xxx", "tenantId": "xxx", "targetProjectId": "xxx", "mfa": { "enrollments": [ { "displayName": "My TOTP", "mfaEnrollmentId": "<步骤1返回的tempEnrollmentId>", "totpInfo": { "verificationCode": "<用户提供的6位验证码>" } } ], "mfaPendingCredential": "<步骤1返回的mfaPendingCredential>" } }
2. 修复控制台UI无TOTP选项问题
如果控制台看不到TOTP选项,需确认租户MFA配置是否完全生效:
- 使用gcloud命令行重新启用租户的TOTP支持:
gcloud alpha identity-toolkit tenants update <租户ID> --project=<项目ID> --enable-totp
- 刷新控制台页面,进入租户的Multi-factor authentication设置,确认TOTP已被添加为允许的第二因素。
3. Golang Admin SDK调整
使用Firebase Admin SDK时,需调用对应的GenerateTotpSecret方法生成密钥,再通过UpdateUser方法提交验证信息,示例代码片段:
// 生成TOTP密钥 secret, err := client.Auth.GenerateTotpSecret(ctx, &auth.GenerateTotpSecretRequest{ LocalID: "xxx", TenantID: "xxx", DisplayName: "My TOTP", }) if err != nil { // 处理错误 } // 假设已获取用户输入的验证码 verificationCode := "123456" // 更新用户完成注册 user, err := client.Auth.UpdateUser(ctx, "xxx", &auth.UserToUpdate{ MFA: &auth.MFAInfo{ Enrollments: []*auth.MFAEnrollment{ { DisplayName: "My TOTP", MFAEnrollmentID: secret.TempEnrollmentID, TOTPInfo: &auth.TOTPInfo{ VerificationCode: verificationCode, }, }, }, MFAPendingCredential: secret.MFAPendingCredential, }, }) if err != nil { // 处理错误 }
内容的提问来源于stack exchange,提问作者Piston Awesome

