了解具有 IAM 权限的组
Cognito Groups with IAM Permissions
我要实现的:
我有一个 Cognito 用户池,我有一些用户和一些组。我希望某些用户可以访问 API 网关功能,一些用户可以访问某些功能,而其他用户则不能访问。
我做了什么:
我创建了三个组并将用户分配给每个组。我为每个组分配了一个 IAM 角色,并为每个角色分配了特定的策略。所有用户的组权限如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "execute-api:*",
"Resource": "*"
}
]
}
我通过无服务器框架创建了 Lambda 函数和 API 网关资源。我将授权方设置为 Cognito 用户池授权方。
(我尝试了一些不同的方法,比如使用联合身份,但似乎效果不佳)
我的结果是什么:
所有用户都可以完全访问 API 网关。给定的权限似乎对每个用户的访问没有任何影响。
帮助:
我做错了什么?
我怎样才能实现我的目标?
我有更好的解决方案,您不需要 IAM。
只需将 {username, serviceName}
对保存在 S3 或 DB 中。所以每次,您都会收到服务请求:
- 检查用户是否获得授权(来自 Cognito)。
- 检查用户是否有权使用该服务(S3、MySQL、RDS 等)。
为什么我觉得更好
因为来自服务的 adding/removing 用户,您不需要以管理员身份登录 IAM。希望以后,您可以创建一个用于管理的仪表板。
工作流程
UserA
向您的 securityApi
发送请求。
SecurityApi
检查令牌是否已授权(用户是否有效)。
如果UserA
有效,则securityApi
发送用户的username
(可以从token的payload中获取)和service name
给一个DB,看用户是否有权限访问该用户。例如 Mysql(为此使用 RDS):
SELECT username from ServiceX LIMIT 1 WHERE username = "xyz";
如果第二步或第三步通过则用户为 1. 有效用户 2. 有权使用该服务。如果用户在步骤 2 或 3 中失败,则用户未被授权使用该服务。
附加到 user pool group
的角色只有在您使用 Cognito Federated Identity
为用户生成凭据时才会出现。 Adding groups to a user pool
IAM roles and their permissions are tied to the temporary AWS
credentials that Amazon Cognito identity pools provide for
authenticated users. Users in a group are automatically assigned the
IAM role for the group when AWS credentials are provided by Amazon
Cognito Federated Identities using the Choose role from token option.
所以基本上
- 创建一个
identity pool
附加到您的用户池。
- 将 API 网关的授权更改为
IAM
- 登录用户池后,用户
id_token
生成federated identity
- 使用此身份 (
secret key + access key + token
) 通过 API 网关进行授权。
现在你的角色应该得到尊重。但请注意 - 您将需要自己生成 AWS SigV4 凭据,因为出于某种原因,这不是开箱即用的。我最终在浏览器中使用 aws-sign-web。
PS:您的角色似乎授予对 API 网关的全面访问权限。您还需要修复它。例如我用来限制对一个 API 端点
的访问的样本角色
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:us-east-2:<aws account id>:<API id>/*/*/acc/*"
],
"Effect": "Allow"
}
]
}
生成示例代码federated identity
function getAccessToken(idToken, idenPoolId, userPool) {
let region = idenPoolId.split(":")[0];
let provider = "cognito-idp." + region + ".amazonaws.com/" + userPool;
let login = {};
login[provider] = idToken;
// Add the User's Id Token to the Cognito credentials login map.
let credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: idenPoolId,
Logins: login
});
//call refresh method in order to authenticate user and get new temp credentials
credentials.get((error) => {
if (error) {
console.error(error);
//let response = {
// statusCode: 500,
// body: JSON.stringify(error)
//};
return null;
} else {
console.log('Successfully logged!');
console.log('AKI:'+ credentials.accessKeyId);
console.log('AKS:'+ credentials.secretAccessKey);
console.log('token:' + credentials.sessionToken);
let response = JSON.stringify({
'AKI': credentials.accessKeyId,
'AKS': credentials.secretAccessKey,
'token': credentials.sessionToken
});
return response;
}
});
}
我要实现的:
我有一个 Cognito 用户池,我有一些用户和一些组。我希望某些用户可以访问 API 网关功能,一些用户可以访问某些功能,而其他用户则不能访问。
我做了什么:
我创建了三个组并将用户分配给每个组。我为每个组分配了一个 IAM 角色,并为每个角色分配了特定的策略。所有用户的组权限如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "execute-api:*",
"Resource": "*"
}
]
}
我通过无服务器框架创建了 Lambda 函数和 API 网关资源。我将授权方设置为 Cognito 用户池授权方。
(我尝试了一些不同的方法,比如使用联合身份,但似乎效果不佳)
我的结果是什么:
所有用户都可以完全访问 API 网关。给定的权限似乎对每个用户的访问没有任何影响。
帮助: 我做错了什么? 我怎样才能实现我的目标?
我有更好的解决方案,您不需要 IAM。
只需将 {username, serviceName}
对保存在 S3 或 DB 中。所以每次,您都会收到服务请求:
- 检查用户是否获得授权(来自 Cognito)。
- 检查用户是否有权使用该服务(S3、MySQL、RDS 等)。
为什么我觉得更好
因为来自服务的 adding/removing 用户,您不需要以管理员身份登录 IAM。希望以后,您可以创建一个用于管理的仪表板。
工作流程
UserA
向您的securityApi
发送请求。SecurityApi
检查令牌是否已授权(用户是否有效)。如果
UserA
有效,则securityApi
发送用户的username
(可以从token的payload中获取)和service name
给一个DB,看用户是否有权限访问该用户。例如 Mysql(为此使用 RDS):SELECT username from ServiceX LIMIT 1 WHERE username = "xyz";
如果第二步或第三步通过则用户为 1. 有效用户 2. 有权使用该服务。如果用户在步骤 2 或 3 中失败,则用户未被授权使用该服务。
附加到 user pool group
的角色只有在您使用 Cognito Federated Identity
为用户生成凭据时才会出现。 Adding groups to a user pool
IAM roles and their permissions are tied to the temporary AWS credentials that Amazon Cognito identity pools provide for authenticated users. Users in a group are automatically assigned the IAM role for the group when AWS credentials are provided by Amazon Cognito Federated Identities using the Choose role from token option.
所以基本上
- 创建一个
identity pool
附加到您的用户池。 - 将 API 网关的授权更改为
IAM
- 登录用户池后,用户
id_token
生成federated identity
- 使用此身份 (
secret key + access key + token
) 通过 API 网关进行授权。
现在你的角色应该得到尊重。但请注意 - 您将需要自己生成 AWS SigV4 凭据,因为出于某种原因,这不是开箱即用的。我最终在浏览器中使用 aws-sign-web。
PS:您的角色似乎授予对 API 网关的全面访问权限。您还需要修复它。例如我用来限制对一个 API 端点
的访问的样本角色{
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:us-east-2:<aws account id>:<API id>/*/*/acc/*"
],
"Effect": "Allow"
}
]
}
生成示例代码federated identity
function getAccessToken(idToken, idenPoolId, userPool) {
let region = idenPoolId.split(":")[0];
let provider = "cognito-idp." + region + ".amazonaws.com/" + userPool;
let login = {};
login[provider] = idToken;
// Add the User's Id Token to the Cognito credentials login map.
let credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: idenPoolId,
Logins: login
});
//call refresh method in order to authenticate user and get new temp credentials
credentials.get((error) => {
if (error) {
console.error(error);
//let response = {
// statusCode: 500,
// body: JSON.stringify(error)
//};
return null;
} else {
console.log('Successfully logged!');
console.log('AKI:'+ credentials.accessKeyId);
console.log('AKS:'+ credentials.secretAccessKey);
console.log('token:' + credentials.sessionToken);
let response = JSON.stringify({
'AKI': credentials.accessKeyId,
'AKS': credentials.secretAccessKey,
'token': credentials.sessionToken
});
return response;
}
});
}