Google Android 上的 AWS Cognito 身份池身份验证失败
Google Authentication fails with AWS Cognito Identity Pool on Android
当我调用 Amazon.CognitoIdentity.AmazonCognitoIdentityClient.GetIdAsync()
时得到 NotAuthorizedException:Token is not from a supported provider of this identity pool
我不明白为什么,令牌是通过 GoogleSignInApi
进行身份验证获得的,并且 AWS Identity Pool 配置为联合到具有相同 "Google WebApp Client ID" 的 Google 身份验证提供程序用于在 Android 设备上进行身份验证。
我还尝试使用 2 种不同的方式获取 Google 令牌
- 在
GoogleSignInOptions
上使用 .RequestIdToken()
的结果
- 通过调用
GoogleAuthUtil.GetToken
API
这两个标记在检查时是不同的,看起来都不错,并且在提供给 AmazonCognitoIdentityClient
时都失败并出现相同的错误。显然,用户在 Android 设备上通过了身份验证,应用程序能够获取电子邮件、显示名称等...
var googleSignInOptions = new
GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
.RequestIdToken("Google WebApp Client ID")
.RequestEmail()
.Build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.EnableAutoManage(
this, // FragmentActivity
this) // OnConnectionFailedListener
.AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
.Build();
mGoogleApiClient.Connect();
var result = await Auth.GoogleSignInApi.SilentSignIn(mGoogleApiClient);
// Only need one or the other, trying to figure out which
var idToken = result.SignInAccount.IdToken;
var authToken = await GetGoogleAuthTokenAsync(result.SignInAccount.Email);
var shortLivedAWScredentials = new CognitoAWSCredentials("identity-pool-id", AWSConfigs.RegionEndpoint);
var cognitoClient = new AmazonCognitoIdentityClient(shortLivedAWScredentials,AWSConfigs.RegionEndpoint);
var logins = new Dictionary<string, string>();
logins["accounts.google.com"] = idToken; // same failure if I use authToken
var request = new GetIdRequest();
request.IdentityPoolId = "identity-pool-id";
request.Logins = logins;
var result = await cognitoClient.GetIdAsync(request); // THIS THROWS Amazon.CognitoIdentity.Model.NotAuthorizedException
private async Task<string> GetGoogleAuthTokenAsync(string accountEmail)
{
Account googleAccount = new Account(accountEmail, GoogleAuthUtil.GoogleAccountType);
string scopes = "audience:server:client_id:" + "Google WebApp Client ID"
var token = await Task.Run(() => { return GoogleAuthUtil.GetToken(this, googleAccount, scopes); });
return token;
}
备注
- 异常发生后,AWS 控制台立即显示 Cognito 身份池增加了 1 个未经身份验证的身份,google 个身份的数量没有变化
经过数小时的搜索,我终于找到了解决方案。基本上 AWS Cognito Identity Pool Federation 到 Google+ 完全被打破了,但不要绝望。您需要做的是 改为联合到 OpenID 提供商。
首先,转到 AWS 控制台 > IAM > 身份提供商 > 创建提供商 > 提供商类型 = OpenID Connect > 提供商 URL = https://accounts.google.com > 受众 = "the Google Client ID for Android or iOS you created in the Google Developer Console"
小心,不要使用 "Google Web App Client ID" 的受众。
其次,转到 AWS 控制台 > Cognito > 联合身份池。 Select 您的身份池,然后单击 "Edit Identity Pool",然后导航到 OpenID 选项卡(不是 Google+ 选项卡,甚至不要使用它不起作用)。您现在应该会看到一个名为 "accounts.google.com" 的复选框,选中它。
第三,去编辑你的移动应用程序源代码,并确保在构建用于调用 GoogleAuthUtil.GetTokenGoogleAuthUtil.GetToken(this, googleAccount, scopes)
.即scopes = "audience:server:client_id:" + "webClientId"
现在您对 var result = await cognitoClient.GetIdAsync(request);
的调用应该会成功。
当我调用 Amazon.CognitoIdentity.AmazonCognitoIdentityClient.GetIdAsync()
NotAuthorizedException:Token is not from a supported provider of this identity pool
我不明白为什么,令牌是通过 GoogleSignInApi
进行身份验证获得的,并且 AWS Identity Pool 配置为联合到具有相同 "Google WebApp Client ID" 的 Google 身份验证提供程序用于在 Android 设备上进行身份验证。
我还尝试使用 2 种不同的方式获取 Google 令牌
- 在
GoogleSignInOptions
上使用 - 通过调用
GoogleAuthUtil.GetToken
API
.RequestIdToken()
的结果
这两个标记在检查时是不同的,看起来都不错,并且在提供给 AmazonCognitoIdentityClient
时都失败并出现相同的错误。显然,用户在 Android 设备上通过了身份验证,应用程序能够获取电子邮件、显示名称等...
var googleSignInOptions = new
GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
.RequestIdToken("Google WebApp Client ID")
.RequestEmail()
.Build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.EnableAutoManage(
this, // FragmentActivity
this) // OnConnectionFailedListener
.AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
.Build();
mGoogleApiClient.Connect();
var result = await Auth.GoogleSignInApi.SilentSignIn(mGoogleApiClient);
// Only need one or the other, trying to figure out which
var idToken = result.SignInAccount.IdToken;
var authToken = await GetGoogleAuthTokenAsync(result.SignInAccount.Email);
var shortLivedAWScredentials = new CognitoAWSCredentials("identity-pool-id", AWSConfigs.RegionEndpoint);
var cognitoClient = new AmazonCognitoIdentityClient(shortLivedAWScredentials,AWSConfigs.RegionEndpoint);
var logins = new Dictionary<string, string>();
logins["accounts.google.com"] = idToken; // same failure if I use authToken
var request = new GetIdRequest();
request.IdentityPoolId = "identity-pool-id";
request.Logins = logins;
var result = await cognitoClient.GetIdAsync(request); // THIS THROWS Amazon.CognitoIdentity.Model.NotAuthorizedException
private async Task<string> GetGoogleAuthTokenAsync(string accountEmail)
{
Account googleAccount = new Account(accountEmail, GoogleAuthUtil.GoogleAccountType);
string scopes = "audience:server:client_id:" + "Google WebApp Client ID"
var token = await Task.Run(() => { return GoogleAuthUtil.GetToken(this, googleAccount, scopes); });
return token;
}
备注
- 异常发生后,AWS 控制台立即显示 Cognito 身份池增加了 1 个未经身份验证的身份,google 个身份的数量没有变化
经过数小时的搜索,我终于找到了解决方案。基本上 AWS Cognito Identity Pool Federation 到 Google+ 完全被打破了,但不要绝望。您需要做的是 改为联合到 OpenID 提供商。
首先,转到 AWS 控制台 > IAM > 身份提供商 > 创建提供商 > 提供商类型 = OpenID Connect > 提供商 URL = https://accounts.google.com > 受众 = "the Google Client ID for Android or iOS you created in the Google Developer Console"
小心,不要使用 "Google Web App Client ID" 的受众。
其次,转到 AWS 控制台 > Cognito > 联合身份池。 Select 您的身份池,然后单击 "Edit Identity Pool",然后导航到 OpenID 选项卡(不是 Google+ 选项卡,甚至不要使用它不起作用)。您现在应该会看到一个名为 "accounts.google.com" 的复选框,选中它。
第三,去编辑你的移动应用程序源代码,并确保在构建用于调用 GoogleAuthUtil.GetTokenGoogleAuthUtil.GetToken(this, googleAccount, scopes)
.即scopes = "audience:server:client_id:" + "webClientId"
现在您对 var result = await cognitoClient.GetIdAsync(request);
的调用应该会成功。