我有一个使用Cognito用户池授权者的Cognito用户池和API网关。池中的每个用户都分配给具有IAM角色的组。借助此设置,客户端将通过Cognito进行身份验证,然后将ID令牌发送到API网关,API网关对请求进行授权并将其传递给Lambda函数。然后,lambda执行其他服务(DynamoDB和S3)。我的问题是我需要在lambda中使用哪些凭证?
一种选择是使用从API网关传递给lambda的ID令牌,以从STS获取临时凭证。基本上,这使我可以使用用户的组IAM角色来访问其他AWS资源,并且外观如下:
var credentials = new CognitoAWSCredentials(
"us-east-1:...", // Identity pool ID
RegionEndpoint.USEast1 // Region
);
credentials.AddLogin(
"cognito-idp.us-east-1.amazonaws.com/us-east-...", // User pool ID
"eyJraWQiOiJi..." // ID token
);
// use credentials to access AWS services
另一种选择是使用分配给Lambda函数的执行角色,但是几乎感觉这似乎更适合于其他方案……也许那些将lambda作为事件的一部分执行的方案?我似乎也不明白如何在lambda本身中获得这些凭据。
还有其他我想念的东西吗?在这里采取什么好方法?
更新
我上面提到的内容几乎是正确的,但并不完全正确。首先,确定您的用户是否需要未经授权的访问。如果是这样,请转到您的身份池并启用未经授权的访问。
要获取未授权用户的访问/秘密密钥,您可以执行以下操作(使用C#SDK,但以下概念适用于其他语言):
var client = new AmazonCognitoIdentityClient(
new AnonymousAWSCredentials(), // We're making public API calls
RegionEndpoint.USEast1); // Your Region
var identityId = await client.GetIdAsync(new GetIdRequest
{
AccountId = "****", // AWS account ID
IdentityPoolId = "us-east-1:****" // Identity Pool ID
});
var credentials = await client.GetCredentialsForIdentityAsync(new GetCredentialsForIdentityRequest()
{
IdentityId = identityId.IdentityId
});
// Use credentials.Credentials when calling AWS services
以上内容将颁发凭据,该凭据具有由您的身份池中定义的未经身份验证的IAM角色定义的权限。
要获取经过身份验证的用户的凭据,请执行以下操作:
var client = new AmazonCognitoIdentityClient(
new AnonymousAWSCredentials(), // We're making public API calls
RegionEndpoint.USEast1); // Your region
var getIdentityIdRequest = new GetIdRequest
{
AccountId = "****", // AWS Account ID
IdentityPoolId = "us-east-1:****" // Identity Pool ID
};
getIdentityIdRequest.Logins.Add(
"cognito-idp.us-east-1.amazonaws.com/us-east-1****", // User Pool ID
idToken); // ID Token
var identityId = await client.GetIdAsync(getIdentityIdRequest);
var getCredentialsRequest = new GetCredentialsForIdentityRequest()
{
IdentityId = identityId.IdentityId
};
getCredentialsRequest.Logins.Add(
"cognito-idp.us-east-1.amazonaws.com/us-east-1****",
idToken);
var credentials = await client.GetCredentialsForIdentityAsync(getCredentialsRequest);
// Use credentials.Credentials when calling AWS services
您将需要ID令牌,因此首先进行身份验证并从响应中获取ID令牌。如果持有ID令牌的用户属于Cognito中具有分配的IAM角色的组,则从上述代码返回的凭据将用于该角色。如果未将用户分配给组或该组没有角色,则将获得分配给身份池的已认证用户IAM角色的凭据。
此外,正如@thomasmichaelwallace所建议的那样,可以从Lambda或从外部API Gateway / Lambda进行上述操作,但前提是您使用的是AWS_IAM Authorizer,因为它是唯一接受密钥和访问密钥进行授权的命令。如果您像我以前一样使用Cognito Authorizer,则需要将ID令牌传递给lambda,并让lambda获得凭据。
答案 0 :(得分:1)
在您的示例中,您为此有效地使用了“内置”方法(Cognito Federated Identities)。可以说,您甚至可以更进一步,使用这些凭据直接从应用程序访问资源(而不是使用API-Gateway + Lambda)。
Lambda中的执行角色是调用lambda的角色(凭证)(不需要设置它们,您也不需要调用new CognitoAWSCredentials
)。正如您所建议的那样,这是为了限制lambda可以执行的操作(基于每个lambda,而不是调用程序)。
如果Cognito联合身份为您工作,那么使用它们就很有意义,因为它们提供了一种使用IAM实施应用程序授权层的方法;可以说意味着您有责任减少建筑量。并非所有应用程序都适合这种模式,这就是AWS为您提供选项的原因。