使用Cognito进行身份验证使特定用户访问S3文件夹。

0

【以下的问题经过翻译处理】 你好,

我一直在尝试使用基于用户名的cognito身份验证生成的令牌从S3获取对象。基本上是所有用户使用一个桶,但每个用户只能访问他们自己文件夹的对象。

我已经阅读了身份池策略,并且已经添加到身份池角色中了。

现在我困惑的是是否使用lambda来拉取对象,还是在客户端使用AWS SDK for JS,或者使用API网关代理到S3。

有什么建议可以实现我想要的内容吗?或者有其他方法吗?

我们正在使用Next JS,React JS和API Gateway的CDK和lambda。

任何帮助都将不胜感激,谢谢。

1 回答
0

【以下的回答经过翻译处理】 你好,

我了解您想了解如何利用Cognito Identity Pool访问AWS服务,如使用GetObject [3]或PutObject [4]功能去访问S3。

以下是我创建的实验,其中我直接利用AWS CLI调用AWS API。您可以选择使用AWS API页面中提到的任何SDK(例如-.NET的AWS SDK,Java V2的AWS SDK,JavaScript的AWS SDK等)来满足您在Lambda代码中相同的用例。


步骤1:创建Cognito用户池 -https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-user-pool.html

步骤2:创建没有客户端密钥的应用程序客户端 -https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html

步骤3:配置应用程序客户端设置 -https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-settings.html

步骤4:设置Cognito域 -https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-assign-domain-prefix.html#cognito-user-pools-assign-domain-prefix-step-1

步骤5:创建身份池 -https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-identity-pool.html

步骤6:在身份池中将用户池添加为身份验证提供程序 -https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-integrating-user-pools-with-identity-pools.html#amazon-cognito-integrating-user-pools-with-identity-pools-configuring

在身份验证提供程序下,指定用户池ID和应用程序客户端ID。在此用户池中的用户现在将与身份池相关联,并可以假定已认证的用户的IAM角色。

步骤7:完成后,您应该能够看到2个角色附加到Identity Pool。我们需要编辑经过身份验证的角色的IAM策略,如下所示:

{
		"Version":"2012-10-17",
		"Statement":[
			{
				"Effect":"Allow",
				"Action":[
					"s3:ListBucket"
				],
				"Resource":[
					"arn:aws:s3:::bucket_name_here"
				],
				"Condition":{
					"StringLike":{
						"s3:prefix":[
							"private-resources/"
						]
					}
				}
			},
			{
				"Effect":"Allow",
				"Action":[
					"s3:GetObject",
					"s3:PutObject",
					"s3:DeleteObject"
				],
				"Resource":[
					"arn:aws:s3:::bucket_name_here/private-resources/${cognito-identity.amazonaws.com:sub}",
					"arn:aws:s3:::bucket_name_here/private-resources/${cognito-identity.amazonaws.com:sub}/*"
				]
			}
		]
	}

身份池中的每个经过身份验证的用户都被分配了一个唯一的 Cognito 身份 ID。 可以在 IAM 策略中将身份 ID 作为 IAM 变量进行访问。 ${cognito-identity.amazonaws.com:sub} 表示分配给身份池中经过身份验证的用户的唯一身份 ID。 上述策略允许用户 User1 将数据和文件放在以其 Cognito Identity ID 命名的文件夹中。 例如,如果用户 1 具有 Cognito 身份 ID - us-east-1:7cbea601-658a-4988-0000-000000000000,则他们可以上传、读取和删除前缀为 private-resources/us-east-1:7cbea601 的文件夹中的文件 -658a-4988-0000-000000000000。 其他用户无法访问此文件夹下的任何文件,该文件夹以 User1 的身份 ID 命名。 请注意,为方便起见,我创建了一个文件夹 private-resources,所有用户都可以在该文件夹下拥有自己的私人文件夹。 您可以省略此操作并将所有私人文件夹直接放在存储桶中。

注意——你也可以使用前缀来限制你的 ListBucket 操作,例如-> “private-resources/$ {cognito-identity.amazonaws.com: sub}”

步骤 8:安装现已完成。第一件事是在用户池中生成用户的ID令牌。你可以进入托管用户界面并登录,你会收到令牌。

第 9 步:获得 ID 令牌后,我们会在 get-id 调用中将 ID 令牌作为登录映射的一部分传递给身份池。get-id 调用将返回用户的唯一身份 ID。有关 get-id API 调用和登录地图结构的更多详细信息可以在以下链接中找到->> https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html

CLI 例子->

$ aws cognito-identity get-id --identity-pool-id "Identity_Pool_ID" --logins "cognito-idp.region.amazonaws.com/Your_UserPool_ID=ID_Token" --region us-east-1

第 10 步:您将收到这种格式的用户的唯一身份 ID ——us-east-x: c9b735c9-72b9-461b-8851-897066xxxxx

步骤 11:在 get-credentials-for-identity API 调用中传递用户的唯一身份 ID 以获取临时 AWS 证书。

https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html

$ aws cognito-identity get-credentials-for-identity --identity-id us-east-x:c9111119-7111-4123-8111-81116xxxxxx --logins "cognito-idp.region.amazonaws.com/Your_UserPool_ID=ID_Token" --region us-east-1

步骤 12:获得临时证书后,使用获得的临时安全证书为 CLI 设置环境变量-https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html

步骤 13:通过为用户拨打电话进行测试。每个 cognito 用户只能访问自己的文件夹。例如,如果 User1 拥有 Cognito Identity ID-us-east-1:7 cbea601-658a-4988-00000000000000,则他们可以上传、读取和删除文件夹中前缀为 privateresources/us-east-1:7 cbea601-658a-4988-000000000000000 的文件。其他用户无法访问这个以 User1 的身份 ID 命名的文件夹下的任何文件。:

$ aws s3api put-object --bucket <BucketName> --key <ObjectKey> --body <body> 

https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html

===========使用AWS CLI 测试 ================ a. 从 Cognito Userpool 检索到的令牌- id_token=eyJraWQ.....Df1pICAoyg access_token=eyJraWQiOi....ZViI2A

b. 在登录参数中使用 ID 令牌调用 getID API

$ aws cognito-identity get-id --identity-pool-id "us-east-x:c7XXXXXXXXXXXXXXXXXc39" --logins "cognito-idp.us-east-x.amazonaws.com/us-east-x_SXXXXXXXX=eyJraWQ.....Df1pICAoyg" --region us-east-x

输出 - { "IdentityId": "us-east-x:e3XXXXXXXXXXXXXXXXXXXXXXXX4" }

c. 调用 getCredentialsfor Identity API 将令牌兑换 IAM 角色/AWS 认证。 输出 - { "IdentityId": "us-east-x:e3XXXXXXXXXXXXXXXXXXXXXXXX4", "Credentials": { "AccessKeyId": "ASIA2XXXXXXXXXXXXXXI", "SecretKey": "1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXF", "SessionToken": "IQ......XXXX3p", "Expiration": "2021-09-04T09:44:38-04:00" } }

d. 配置证书(accessKeyID、secretKey、SessionToken)后你可以调用 S3 putObject 或 getObject-

$ aws s3api put-object --bucket teXXXXXXXXXXXXXXXXXXXXXXXn --key private-resources/us-east-x:e3XXXXXXXXXXXXXXXXXXXXXXXX4/swagger --body swagger.json --profile cognitotest
{
    "ETag": "\"b124..............330\""
}

或者根据你的用例,你也可以调用 getObject API->

$ aws s3api get-object --bucket teXXXXXXXXXXXXXXXXXXXXXXXn --key private-resources/us-east-x:us-east-x:e3XXXXXXXXXXXXXXXXXXXXXXXX4 "helloworld" --profile cognitotest

现在关于开发中的查询,请注意,我们有专门的 AWS Solutions Architect 团队,负责处理自定义解决方案的架构和设计级别查询。我建议您直接联系我们的销售团队,因为他们可以帮助您与我们的解决方案架构师 (SA) 团队取得联系。

您可以使用以下任何一种方法请求销售(业务开发)团队的成员与您联系:

>> Via form:    	http://aws.amazon.com/contact-us/aws-sales/
>> Via Live Chat:   https://pages.awscloud.com/live-chat-contact-us.html
>> Phone support:   +1 (833) 662-9873 - 6:30am - 4:00pm (Pacific) Monday - Friday.

如果你有任何关于 Cognito SDK 的疑问,也可以在 Github 上联系开发团队。 https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js

我希望上面分享的实验室能够澄清使用 AWS API 调用利用 Identity Pool 的用例,也可以在 AWS CLI 或使用 SDK 的代码中利用这些用例。如果您有任何问题或疑虑,请随时与我们的高级支持团队一起创建支持案例,与我们联系。

参考链接: [1] https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html

[2] https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html

[3] https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html

[4] https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html

profile picture
专家
已回答 2 年前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则