admin管理员组

文章数量:1025244

I have cognito users that will write to an S3 bucket(s). I'm assuming the following process (But perhaps there's a better one?):

1) Create the bucket

2) Have the user authenticate with cognito and then write their resource to the bucket.

3) Let the user retrieve the resource from the bucket, but only if the user wrote the resource to the bucket (An additional requirement is that the object has to be tagged with a boolean value that is set to true, so I'm asuming it has to go through a lambda endpoint to do this?).

One thing that crossed my mind is that maybe there's a way to create buckets that are only accessible by the user, that way each user has their own bucket?

The other thing to came to mind is to tag the object with user id and only allow a lambda endpoint to return the object if the user has the correct user id and the boolean valued tag is set to true.

Thoughts?

I have cognito users that will write to an S3 bucket(s). I'm assuming the following process (But perhaps there's a better one?):

1) Create the bucket

2) Have the user authenticate with cognito and then write their resource to the bucket.

3) Let the user retrieve the resource from the bucket, but only if the user wrote the resource to the bucket (An additional requirement is that the object has to be tagged with a boolean value that is set to true, so I'm asuming it has to go through a lambda endpoint to do this?).

One thing that crossed my mind is that maybe there's a way to create buckets that are only accessible by the user, that way each user has their own bucket?

The other thing to came to mind is to tag the object with user id and only allow a lambda endpoint to return the object if the user has the correct user id and the boolean valued tag is set to true.

Thoughts?

Share Improve this question edited Apr 11, 2018 at 19:25 Ole asked Apr 11, 2018 at 18:50 OleOle 47.6k70 gold badges238 silver badges447 bronze badges 3
  • What do you mean by "cognito users that will write to an S3 bucket(s)"? You have for example web app with cognito authentication and users can upload to S3 via AWS JavaScript SDK? – Michał Z. Commented Apr 11, 2018 at 19:36
  • Correct - Webapp with cognito authentication and file upload to the bucket or buckets (If S3 supports dedicated buckets or bucket namespaces assigned to each user) and AWS access via the javascript SDK or perhaps just using REST and passing the request through the AWS gateway where such that the application can be verified before bucket access occurs. – Ole Commented Apr 11, 2018 at 19:49
  • Also found this tutorial helpful in addition to all the great material in @MichaelZs answer: sanderknape./2017/08/… – Ole Commented Apr 12, 2018 at 18:34
Add a ment  | 

1 Answer 1

Reset to default 6

It can be done like this:

  • S3 Bucket - one bucket will be used for all users files.

  • IAM Role - with policy statement that allow write objects for bucket above.

  • Lambda Function - will assume role above and return temporary credentials.

Store files under path same as Cognito username for every user (e.g. s3://my-bucket/some-user/file.zip)

DOWNLOAD FROM S3:

Lambda function can generate pre-signed URL and return it. Check if Cognito username (from JWT) equals folder name (if not - return e.g. 403 status) or - as input just get filename and concatenate Cognito username and filename.

Example (Node.js):

...
const preSignedUrl = s3.getSignedUrl('getObject', {
    Bucket: '<BUCKET NAME>',
    Key: '<cognito user name>/<file name>', // path to object in bucket above
    Expires: 3600 // expiration time in seconds
});
....

Lambda role requires policy that allows read objects from bucket.

UPLOAD TO S3:

Lambda function can assume role (important: restrict policy only for cognito user name folder - e.g. s3://my-bucket/some-user/*) and return temporary credentials. With them - user can upload to S3 from browser only to his directory.

Example (Node.js):

...
const BUCKET_NAME = <...>
const COGNITO_USER_NAME = <...>

const restrictedPolicy = {
    Version:'2012-10-17',
    Statement: [{
        Effect: 'Allow',
        Action: 's3:PutObject',
        Resource: `arn:aws:s3:::${BUCKET_NAME}/${COGNITO_USERNAME}/*`
    }]
}

sts.assumeRole({
    DurationSeconds: 3600, // expiration time in seconds
    RoleArn: '<...>', // role that has write access to whole s3 bucket
    RoleSessionName: '<cognito username>', // not much importance
    Policy: JSON.stringify(restrictedPolicy) // write access only for Cognito username folder
}, (err, data) => {
    if(err) {
        ...
    } else {
        const temporaryCredentials = data.Credentials // Lambda needs to return that to API Gateway via callback
        ...
    }
});
...

Lambda role requires policy that allows assume role.

I have cognito users that will write to an S3 bucket(s). I'm assuming the following process (But perhaps there's a better one?):

1) Create the bucket

2) Have the user authenticate with cognito and then write their resource to the bucket.

3) Let the user retrieve the resource from the bucket, but only if the user wrote the resource to the bucket (An additional requirement is that the object has to be tagged with a boolean value that is set to true, so I'm asuming it has to go through a lambda endpoint to do this?).

One thing that crossed my mind is that maybe there's a way to create buckets that are only accessible by the user, that way each user has their own bucket?

The other thing to came to mind is to tag the object with user id and only allow a lambda endpoint to return the object if the user has the correct user id and the boolean valued tag is set to true.

Thoughts?

I have cognito users that will write to an S3 bucket(s). I'm assuming the following process (But perhaps there's a better one?):

1) Create the bucket

2) Have the user authenticate with cognito and then write their resource to the bucket.

3) Let the user retrieve the resource from the bucket, but only if the user wrote the resource to the bucket (An additional requirement is that the object has to be tagged with a boolean value that is set to true, so I'm asuming it has to go through a lambda endpoint to do this?).

One thing that crossed my mind is that maybe there's a way to create buckets that are only accessible by the user, that way each user has their own bucket?

The other thing to came to mind is to tag the object with user id and only allow a lambda endpoint to return the object if the user has the correct user id and the boolean valued tag is set to true.

Thoughts?

Share Improve this question edited Apr 11, 2018 at 19:25 Ole asked Apr 11, 2018 at 18:50 OleOle 47.6k70 gold badges238 silver badges447 bronze badges 3
  • What do you mean by "cognito users that will write to an S3 bucket(s)"? You have for example web app with cognito authentication and users can upload to S3 via AWS JavaScript SDK? – Michał Z. Commented Apr 11, 2018 at 19:36
  • Correct - Webapp with cognito authentication and file upload to the bucket or buckets (If S3 supports dedicated buckets or bucket namespaces assigned to each user) and AWS access via the javascript SDK or perhaps just using REST and passing the request through the AWS gateway where such that the application can be verified before bucket access occurs. – Ole Commented Apr 11, 2018 at 19:49
  • Also found this tutorial helpful in addition to all the great material in @MichaelZs answer: sanderknape./2017/08/… – Ole Commented Apr 12, 2018 at 18:34
Add a ment  | 

1 Answer 1

Reset to default 6

It can be done like this:

  • S3 Bucket - one bucket will be used for all users files.

  • IAM Role - with policy statement that allow write objects for bucket above.

  • Lambda Function - will assume role above and return temporary credentials.

Store files under path same as Cognito username for every user (e.g. s3://my-bucket/some-user/file.zip)

DOWNLOAD FROM S3:

Lambda function can generate pre-signed URL and return it. Check if Cognito username (from JWT) equals folder name (if not - return e.g. 403 status) or - as input just get filename and concatenate Cognito username and filename.

Example (Node.js):

...
const preSignedUrl = s3.getSignedUrl('getObject', {
    Bucket: '<BUCKET NAME>',
    Key: '<cognito user name>/<file name>', // path to object in bucket above
    Expires: 3600 // expiration time in seconds
});
....

Lambda role requires policy that allows read objects from bucket.

UPLOAD TO S3:

Lambda function can assume role (important: restrict policy only for cognito user name folder - e.g. s3://my-bucket/some-user/*) and return temporary credentials. With them - user can upload to S3 from browser only to his directory.

Example (Node.js):

...
const BUCKET_NAME = <...>
const COGNITO_USER_NAME = <...>

const restrictedPolicy = {
    Version:'2012-10-17',
    Statement: [{
        Effect: 'Allow',
        Action: 's3:PutObject',
        Resource: `arn:aws:s3:::${BUCKET_NAME}/${COGNITO_USERNAME}/*`
    }]
}

sts.assumeRole({
    DurationSeconds: 3600, // expiration time in seconds
    RoleArn: '<...>', // role that has write access to whole s3 bucket
    RoleSessionName: '<cognito username>', // not much importance
    Policy: JSON.stringify(restrictedPolicy) // write access only for Cognito username folder
}, (err, data) => {
    if(err) {
        ...
    } else {
        const temporaryCredentials = data.Credentials // Lambda needs to return that to API Gateway via callback
        ...
    }
});
...

Lambda role requires policy that allows assume role.

本文标签: javascriptCognito User authorization to access an s3 objectStack Overflow