【发布时间】:2020-12-05 23:19:16
【问题描述】:
我正在使用 AWS Cognito 用户池组来管理 API Gateway API 的权限。我相信这是对组的有效用途,因为这里的文档是这样说的:https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-user-groups.html#using-groups-to-control-permission-with-amazon-api-gateway。
不幸的是,据我所知,该用例的文档基本上不存在(除了那一小段)。我试图弄清楚这如何与自定义 API 网关授权 Lambda 函数一起使用。我创建了一个测试角色并将其分配给 Cognito 中的一个测试组。该角色附加了一个策略,但将来这些角色将有多个策略。
现在,在我的自定义授权中,我已经在验证访问令牌等,一切正常。我现在正在尝试在使用组/角色/策略时添加这种细粒度的访问控制。我已经安装了 IAM SDK 并一直在挖掘我需要进行哪些调用。似乎没有简单的方法来获得一个角色和它的所有政策。我想出的最好的方法如下:
public async Task<IEnumerable<string>> GetGroupPermissionsForUserAsync(Models.User user)
{
if (!user.UserAttributes.TryGetValue(UserAttributeName.UserPoolId, out var userPoolId))
{
return null;
}
var groups = await GetUserGroups(user.Username, userPoolId);
var groupRoleArn = groups.FirstOrDefault()?.RoleArn;
var policies = new List<string>();
if (!string.IsNullOrWhiteSpace(groupRoleArn))
{
var roleName = groupRoleArn.Substring(groupRoleArn.IndexOf('/') + 1);
var rolePoliciesResponse = await _iamClient.ListAttachedRolePoliciesAsync(new ListAttachedRolePoliciesRequest { RoleName = roleName });
foreach (var rolePolicy in rolePoliciesResponse.AttachedPolicies)
{
var policyVersionsResponse = await _iamClient.ListPolicyVersionsAsync(new ListPolicyVersionsRequest
{
PolicyArn = rolePolicy.PolicyArn
});
var latestPolicyVerson = policyVersionsResponse.Versions.OrderByDescending(x => x.CreateDate).LastOrDefault();
var policyVersionResponse = await _iamClient.GetPolicyVersionAsync(new GetPolicyVersionRequest
{
PolicyArn = rolePolicy.PolicyArn,
VersionId = latestPolicyVerson.VersionId
});
if (!string.IsNullOrWhiteSpace(policyVersionResponse?.PolicyVersion.Document))
{
policies.Add(HttpUtility.UrlDecode(policyVersionResponse.PolicyVersion.Document));
}
}
}
return policies;
}
private async Task<IEnumerable<GroupType>> GetUserGroups(string username, string userPoolId)
{
string nextToken = null;
var groups = new List<GroupType>();
do
{
var response = await _cognitoClient.AdminListGroupsForUserAsync(new AdminListGroupsForUserRequest
{
Username = username,
UserPoolId = userPoolId
});
groups.AddRange(response.Groups);
nextToken = response.NextToken;
} while (!string.IsNullOrWhiteSpace(nextToken));
return groups.OrderBy(x => x.Precedence);
}
如您所见,我必须进行大量调用才能获取某个角色的策略。
-
_cognitoClient.AdminListGroupsForUserAsync从 Cognito 获取用户组。 -
_iamClient.ListAttachedRolePoliciesAsync获取与角色关联的策略。 -
_iamClient.ListPolicyVersionsAsync获取每个策略的版本。 -
_iamClient.GetPolicyVersionAsync获取最终有政策文件的个人政策版本。
ListPolicyVersionsAsync 返回带有文档属性的响应,但由于某种原因它始终为 null,因此需要额外的 GetPolicyVersionAsync 调用。
这不仅会增加延迟(这是授权函数上的一个问题,每次调用 API 都将通过此代码运行),而且它只给我留下了一堆我需要以某种方式执行的单独策略在返回 API 网关之前进行重复数据删除。
真的没有更简单/更快的方法可以做到这一点吗?有没有办法用更少的调用来获取所有这些信息?有没有办法在它们的规则重叠的情况下扁平化策略?
【问题讨论】:
标签: c# amazon-web-services aws-sdk amazon-cognito amazon-iam