Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为AWS S3中的权限指定IAM角色_Python_Amazon Web Services_Amazon S3_Boto_Amazon Cognito - Fatal编程技术网

Python 为AWS S3中的权限指定IAM角色

Python 为AWS S3中的权限指定IAM角色,python,amazon-web-services,amazon-s3,boto,amazon-cognito,Python,Amazon Web Services,Amazon S3,Boto,Amazon Cognito,我试图将所有AWS Cognito用户限制在S3存储桶中他们自己的子目录中 我不希望他们在我的大存储桶中列出、读取或写入其他人的子目录/文件,我只希望他们在自己的目录中读取和写入对象 我在汲取灵感 我的政策是: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucke

我试图将所有AWS Cognito用户限制在S3存储桶中他们自己的子目录中

我不希望他们在我的大存储桶中列出、读取或写入其他人的子目录/文件,我只希望他们在自己的目录中读取和写入对象

我在汲取灵感

我的政策是:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "subfolder/"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket/subfolder/${cognito-identity.amazonaws.com:sub}",
                "arn:aws:s3:::my-bucket/subfolder/${cognito-identity.amazonaws.com:sub}/*"
            ]
        }
    ]
}
以及我的代码,用于检索具有user_id=
test@test.com
,但实际上允许我检索受限制的文件:

import boto

# These keys are *not* hardcoded, I'm just leaving out
# the auth flow to get them from Cognito/STS as described 
# here: https://mobile.awsblog.com/post/Tx2FL1QAPDE0UAH/Understanding-Amazon-Cognito-Authentication-Part-2-Developer-Authenticated-Ident
conn = boto.s3.connect_to_region('us-east-1',
    aws_access_key_id=ACCESS_KEY_FROM_COGNITO,
    aws_secret_access_key=SECRET_KEY_FROM_COGNITO,
    security_token=SECURITY_KEY_FROM_COGNITO)

# get the bucket
b = conn.get_bucket('my-bucket', validate=False)

# try to get an object we SHOULD be able to get
k = Key(b)
k.key = 'subfolder/us-east-1:xxxx-xxxx-xxxx-xxxxxxxxx/foobar'
print "Contents:", k.get_contents_as_string()  # success!

# try to get and object we SHOUDN'T be able to get
k2 = Key(b)
k2.key = 'subfolder/BLAH_BLAH/restricted'
print "Contents:", k2.get_contents_as_string()  # should fail, but doesn't
不幸的是,我可以访问和读取这两个文件的内容,但我在AWS博客文档文章中遵循了完全相同的模式。我也不确定为什么我需要boto连接中的
validate=False
,但它似乎工作得很好

我错过了什么


编辑:为了回答下面的问题,我尝试将我的角色更新为以下内容,但这并没有什么不同:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "subfolder/${cognito-identity.amazonaws.com:sub}/*"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket/subfolder/${cognito-identity.amazonaws.com:sub}/*"
            ]
        }
    ]
}
我还确认了我使用的访问凭据来自Cognito,方法是使用从STS检索的访问/机密/安全令牌三元组,使用Cognito令牌创建一个
boto
对象,并为我的身份池查询与身份验证Cognito用户对应的我的角色名。在这样做的过程中,我在尝试读取此角色时遇到了以下异常(由于我没有授予访问权限,因此应该发生这种情况):

所以仍然不清楚为什么这不起作用

5件事:

  • 确保您使用的是Amazon Cognito Identity服务颁发的凭据,否则${Cognito Identity.amazonaws.com:sub}将为空并授予您对所有内容的访问权限
  • 确保您正在使用的Amazon Cognito标识凭据是在更新策略后发布的,该策略嵌入到凭据的会话部分中,因此如果您使用的是旧凭据,它们可能没有附加当前策略
  • 您不能使用用户的用户名,必须使用Amazon Cognito标识idtest@test.com它将是身份id:us-east-1:beef-beef-beef-XXXXXXXX
  • 您的池有2个与之关联的角色,一个未经身份验证的角色和一个经过身份验证的角色。确保将策略设置为正确的角色,在这种情况下,看起来您使用的是开发人员身份验证的身份,应该修改身份验证角色的策略
  • 检查您的S3 bucket策略,如果您允许匿名访问您的bucket,Cognoto角色策略将不会覆盖它。如果是这种情况,请关闭匿名访问
    看起来您的代码使用的是硬编码的访问密钥和密钥,而不是使用Cognito检索凭据。与为所有用户嵌入相同的访问密钥和密钥不同,要利用Cognito,您需要遵循并使用GetId(,)获取标识ID,然后使用GetCredentialsForIdentity()获取当前ID的Cognito颁发的凭据。然后将这些凭据与boto S3连接一起使用


    还要确保缓存每个用户的ID,并在调用Cognito时重用它。

    答案相当愚蠢。显然,S3中的bucket本身有自己的策略(它们相当隐蔽),但我有一个指令:

    Principal: "*"
    
    这使得bucket具有全球可读性

    第二个启示是,如果您使用
    s3:ListBucket
    条件限制一个bucket,这并不意味着如果您列出该bucket,您将只得到这些结果—您必须按名称调用它。例如,
    boto

    wrong = bucket.list()  # will simply 403
    right = bucket.list(prefix="base/subdir/<cognito-id>/")  # will succeed
    
    error=bucket.list()#只需403
    右=bucket.list(prefix=“base/subdir/”)#将成功
    
    换句话说,S3的设计使您必须知道所需文件夹的前缀键,这是一个很好的实践


    我必须说,AWS的人们在这里和他们的论坛上对诊断这个问题的帮助给我留下了深刻的印象。总之,现在对S3有了更好的理解。

    很有趣。关于你的观点的问题:1)我如何测试这一点?我能看到这是否是非空的吗?以及3)我如何从我的角度看到我的开发人员用户ID之间的映射(test@test.com)AWS的问题呢?我已经用讨论过的一些要点更新了这个问题,但仍然不起作用。嗯。我也在3)上找到了你观点的答案。在你向STS索要凭证之前,只要Cognito授予你网络令牌,就会给出这个标识ID。嗯,是的,我知道。我有两个角色,一个用于已验证,另一个用于未经验证。我将此标记为答案,因为它可能是我面临的问题以及试图调试自己问题的人员的最有用的信息。您能否澄清更改后哪些问题不起作用,是否与原始问题相同(您可以访问子文件夹下的任何密钥)还是别的?是的,同样的问题。当我的
    GetObject
    PutObject
    访问权限应限于用户文件夹时,我可以访问任何键。此外,我可以列出整个bucket中的所有对象,而不仅仅是具有指定前缀的对象。您的bucket策略中是否有允许比您的角色更多访问的特殊内容?除了您在此处列出的角色之外,您是否还有其他附加到该角色的策略?如果您在我们的论坛上发表文章或以其他方式向我们获取您的帐户id,我们还可以查看您的帐户详细信息并进行更仔细的调试。@BobKinney:没有其他角色,我知道我的bucket中没有什么特别的内容。不过肯定有什么地方出了问题。不,我只是没有发布整个身份验证流程的代码。我(正如我在帖子中提到的)正在联系Cognito和STS以获得钥匙。此外,您提到的流程效率很低,您可以简单地使用
    GetOpenIDTokenForDeveloperIdentity
    并从那里
    assumeWitheBidentity
    与STS-关联。请参阅我文章的最后一段,其中有相关的403
    wrong = bucket.list()  # will simply 403
    right = bucket.list(prefix="base/subdir/<cognito-id>/")  # will succeed