【发布时间】:2021-03-05 10:28:50
【问题描述】:
我正在使用 Xamarin 跨平台开发应用程序 IOS 和 Android。 我正在努力使用从 Cognito Identity 接收的凭据来授权应用调用 API Gateway。
我的用户流是:
- 在 Cognito 用户池上进行身份验证并获取令牌
- 用令牌交换 Cognito 身份池上的凭据
- 使用在上一步中检索到的凭据访问 API Gateway。
第 1 步和第 2 步似乎工作正常。但是当应用程序尝试连接到 api 网关时,它会收到错误 403 (Forbidden)。
我的代码:
- 在 Cognito 用户池上进行身份验证并获取令牌
**
public async Task<AppUser> Login(string username, string password)
{
CognitoUser cognitoUser = new CognitoUser(username, Aws.COGNITO_CLIENT_ID, CognitoUserPool, CognitoIdentityProviderClient);
AppUser appUser = new AppUser() { Email = username };
// Send a login request and wait for the response from Amazon
try
{
AuthFlowResponse response = await cognitoUser.StartWithSrpAuthAsync(new InitiateSrpAuthRequest()
{
Password = password
});
;
appUser.IsAuthenticated = true;
}
catch (NotAuthorizedException e)
{
appUser.IsAuthenticated = false;
appUser.ErrorMessage = e.Message;
}
await _tokenManagement.SaveTokens(cognitoUser.SessionTokens) ;
return appUser;
}
- 用令牌交换 Cognito 身份池上的凭据
**
public async Task<ImmutableCredentials> GetAppCredentialsAsync()
{
CognitoAWSCredentials cac;
if (_tokenManagement.CheckIsAnonymous())
{
//Anonymous credentials
cac = new CognitoAWSCredentials(Aws.COGINITO_IDENTITY_POLL_ID, RegionEndpoint.USEast1);
}
else
{
//Retrieve saved tokens from previous authentication
var tm = await _tokenManagement.RetrieveTokens();
CognitoUser user = new CognitoUser(null, Aws.COGNITO_CLIENT_ID, CognitoUserPool, CognitoIdentityProviderClient)
{
SessionTokens = new CognitoUserSession(tm.IdToken, tm.AccessToken, tm.RefreshToken, tm.IssuedTime, tm.ExpirationTime)
};
//Retrieve authenticated credentials
cac = user.GetCognitoAWSCredentials(Aws.COGINITO_IDENTITY_POLL_ID, RegionEndpoint.USEast1);
}
}
return await cac.GetCredentialsAsync();
}
- 使用在上一步中检索到的凭据访问 API Gateway:
**
public async Task<IList<MediaImage>> GetCoversAWSAsync()
{
// Getting credentials and sign request
var request = await BuildRequestAsync("/listMedia");
var client = new HttpClient();
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
IList<MediaImage> covers = JsonConvert.DeserializeObject<IList<MediaImage>>(await response.Content.ReadAsStringAsync());
return covers;
}
private async Task<HttpRequestMessage> BuildRequestAsync(string service)
{
var request = new HttpRequestMessage()
{
Method = HttpMethod.Get,
RequestUri = new Uri(baseURL + service)
};
ImmutableCredentials awsCredential = await _loginService.GetAppCredentialsAsync( );
var signer = new AWS4RequestSigner(awsCredential.AccessKey, awsCredential.SecretKey);
request = await signer.Sign(request, "execute-api", awsRegion);
return request;
}
当我硬编码来自一个 IAM 用户的凭据时,此代码可以正常工作。但是从 Cognito Identities 检索到的凭据却出现了 Forbidden 错误。 我使用 SDK for S3 进行了测试,我能够成功列出具有从 Cognito Identities 接收到的相同凭据的存储桶,但无法在 API 网关上发出请求。
你能帮帮我吗?我在哪里迷路了?
【问题讨论】:
标签: amazon-web-services aws-api-gateway amazon-cognito aws-sdk-net