如何配置我的 AWS-SFTP-SERVER/AWS-COGNITO-USER-POOL 以提供访问池的所有现有和新用户访问 AWS SFTP 服务器的权限...
所以经过大量研究终于能够找到一些好作品......
AWSSFTP 服务器可以使用将在 Cognito 用户池中创建的用户名/密码进行身份验证,但 AWS 不提供内置的此功能。 我们需要为相同的方式创建 API 门路。
SFTP -> 自定义身份提供程序 -> API 网关 -> Lambda -> Cognito 用户池
很快我将发布相同的 Lambda 代码。
经过大量的工作和调试,我终于找到了秘诀。 我将在这里尽快分解它。 首先,这是我的用例。
- 使用密码而不是 ssh 密钥的 AWS SFTP
- 用户的主目录必须为分支
- 用户能够与他人共享目录
- 无需保护和管理新的 API 网关
这是我解决它的方法:
使用- "使用 AWS Lambda 连接您的身份提供商"设置 sftp 服务器。 这很重要,因为这意味着您不必设置 api 网关
- 创建 Cognito 用户池,并确保您具有名为 HOME_DIR 的 cutom 属性。 不要忘记在应用程序集成部分中将字段设置为可读,否则它不会在 IdToken 字段中。 创建用户池时,请确保您不需要 hashsecret,否则您的 lambda 将无法 AdminInititateAuth
- 创建一个角色,使传输服务能够执行 S3 操作(图 1(
- 编写一个 lambda 调用sftp_auth。 请注意,重要性在于有效负载结构,如下所示:
{
Role: "arn:aws:iam::123456789012:role/SFTPS3Role", // policy attached to this role is defined in figure 2
HomeDirectoryDetails: JSON.stringify([{Entry: "/", Target: "/mybucket/sftp/username"}]), // sets the virtual home directory
HomeDirectoryType: "LOGICAL", // forces the chrooting
Password: "xxxx" // Not sure this one is strictly necessary
}
图 2 如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
"s3-object-lambda:*"
],
"Resource": "*"
}
]
}
最后,这里是lambda的来源:
import AWS from 'aws-sdk';
import jwt_decode from "jwt-decode";
/**
* sample payload:
* {
"username": "username",
"sourceIp": "192.168.1.1",
"protocol": "SFTP",
"serverId": "s-12345679012",
"password": "xxxxxxxxxxxxx"
}
*/
const HOME_DIR_ATTR = "custom:HOME_DIR";
export const handler = async(event) => {
console.log(`event body = ${JSON.stringify(event)}`);
let payload = event; // TODO: consider making event more flexible
let USER_POOL_CLIENT_ID = "xxxclientidxxx";
let USER_POOL_ID = "xxxxpoolidxxxx";
AWS.config.update({region: 'us-east-1'});
const cognito = new AWS.CognitoIdentityServiceProvider();
let params = {
AuthFlow: "ADMIN_NO_SRP_AUTH",
ClientId: USER_POOL_CLIENT_ID, // From Cognito dashboard
UserPoolId: USER_POOL_ID,
AuthParameters: {
USERNAME: payload.username,
PASSWORD: payload.password
}
};
const jwtContainer = await cognito.adminInitiateAuth(params).promise();
console.log(`jwtContainer = ${JSON.stringify(jwtContainer)}`);
let authResult = jwtContainer["AuthenticationResult"];
console.log(`${JSON.stringify(authResult)}`);
let token = authResult["IdToken"];
console.log("token = "+token);
let decoded = jwt_decode(token);
console.log("decoded = "+JSON.stringify(decoded));
console.log("homedir = "+decoded[HOME_DIR_ATTR]);
let response = {
Role: "arn:aws:iam::123456789012:role/SFTPS3Role",
HomeDirectoryDetails: JSON.stringify([{Entry: "/", Target: decoded[HOME_DIR_ATTR]}]),
HomeDirectoryType: "LOGICAL",
Password: payload.password
};
return response;
};
其他说明:我的 lambda 代码依赖于公共 npm 包中的 2 层:aws-sdk(提供 cognito 客户端(和 jwt-decode(提供一个库来解码使用 cognito 客户端登录后返回的 id 令牌,而无需再次验证 idtoken(。 确保您有这 2 层,否则这些都不起作用。