Home > Blockchain >  VueJS aws-sdk acces to dedicated S3 bucket for authenticated Cognito user
VueJS aws-sdk acces to dedicated S3 bucket for authenticated Cognito user

Time:02-21

Hi everyone i'm turning around for more than one day now and can find out where the problem is.

What i need:

  1. Authenticate my user on my web app to control acces to a bucket
  2. allow each user to acces only a specific folder in my bucket

What i have done

  1. Create a cognito user group with client application and federated pool
  2. Linked my federated pool to my Cognito User Group
  3. create a bucket with following props

A. Public access enter image description here B. CORS enter image description here

C. Create a login form in vuejs and start authentictate to cognito with the AWS-SDK

<script >
import * as AmazonCognitoIdentity from 'amazon-cognito-identity-js'
import * as AWS from 'aws-sdk'
import AwsConfig from '@/config/ConfigAws.js'

export default {
  data () {
    return {
      username: '',
      password: '',
      email: '',
      access_token: null,
      id_token: null,
  
    }
  },
 methods: {

    
    AWS_auth () {
AWS.config.update({ region: AwsConfig.default_region })
var authenticationData = {
        Username: this.email,
        Password: this.password
      }
var userData = {
        Username: this.email,
        Pool: userPool
      }
var poolData = {
        UserPoolId: AwsConfig.cognito_UserPoolId,
        ClientId: AwsConfig.cognito_client_ID
      }
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData)
      var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData)
      cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: (result) => {
          console.log('success auth')
          // isolate acces token
          var accessToken = result.getAccessToken().getJwtToken()
          // isolate id token, id token has to get used for API gateway auth
          var idToken = result.idToken.jwtToken
          // Update AWS config credentials to store credentials for the session
          AWS.config.credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: 'eu-west-1:aaaaaaaaa-XXXXX-4a99-b606-YYYYYYYYYY',
            Logins: { 'cognito-idp.eu-west-1.amazonaws.com/eu-west-1_jjrr8877rL': idToken }
          })
          // store in template data both token
          this.access_token = accessToken
          this.id_token = idToken
          // store in local storage both token, this storage is helpfull at new connexion, to avoir connexion path
          localStorage.labelingAPPAccessToken = accessToken
          localStorage.labelingAPPIdToken = idToken
          this.$store.state.UserAccesToken = localStorage.labelingAPPAccessToken
          // Get COgnito UserData and custom data    
          var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider()
          cognitoidentityserviceprovider.getUser(
            {
              AccessToken: accessToken /* required */
            },
            (err, data, vm) => {
              if (err) {console.log(err,  err.stack)}
              if (data) { console.log('Authentication success') }
              var newdata = data.UserAttributes
              Object.assign(newdata, { IdentityID: String(AWS.config.credentials.identityId) })
              localStorage.setItem('SessionFaaSPlateformStorage4f66b04b5460f2a9d13b', JSON.stringify(newdata))
              this.$store.state.Userdata = newdata
              this.loader_active = false
              this.$router.push('Dashboard/DashboardHome')

              if (err) {
                console.log(err, err.stack)
              }
            }
          )
          console.log('IdentityID')
          console.log(String(AWS.config.credentials.identityId))
        },

        onFailure: function (err) {
          console.log('Auth failed')
          console.log(err, err.stack)
        }
      })
    }
  }
</script >

So Far so good i get all what i need, my different token, userId, UserDate and AppID

  1. configure different Role and policy to allow user to use AWS services. I retrieve the "plateform_cognito_Role, generated and linked to my federated user pool with following content

A. Trust relationship enter image description here

B. permission => linked to a custom policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*"
            ],
            "Resource": [
                "arn:aws:cognito-sync:eu-west-1:454545454545:identitypool/eu-west-1_sssssssss/identity/*/dataset/*",
                "arn:aws:cognito-sync:eu-west-1:454545454545:identitypool/eu-west-1_sssssssss",
                "arn:aws:cognito-sync:eu-west-1:454545454545:identitypool/eu-west-1_sssssssss/identity/*"
            ]
        },
        {
            "Sid": "VisualEditordynamo",
            "Effect": "Allow",
            "Action": [
                "dynamodb:BatchGetItem",
                "dynamodb:PutItem",
                "dynamodb:GetItem",
                "dynamodb:Scan",
                "dynamodb:Query",
                "dynamodb:UpdateItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:eu-west-1:454545454545:table/FaasCloudPlateform_Functions/index/*",
                "arn:aws:dynamodb:eu-west-1:454545454545:table/FaasCloudPlateform_Functions",
                "arn:aws:dynamodb:eu-west-1:454545454545:table/FaasCloudPlateform_Users/index/*",
                "arn:aws:dynamodb:eu-west-1:454545454545:table/FaasCloudPlateform_Users"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::faascloudplatform",
                "arn:aws:s3:::faascloudplatform/*"
            ]
        }
    ]
}

At this stage everything is working like a charm, i can interact with dynamo and S3 with absolutely no problem.

Now i want to isolate every cognito user to only have access to his own specific folder in the bucker

i modify the previous policy like

{
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::faascloudplatform/Users/${cognito-identity.amazonaws.com:sub}",
                "arn:aws:s3:::faascloudplatform/Users/${cognito-identity.amazonaws.com:sub}/*"
            ]
 }

On authentication in my client web app the Identity Id looks like "eu-west-1:fec78-0000-36b-80bd-8e1c54ce" witch seems fine, So i go to my S3 storage, create a folder with my Identity Id name and put a test file in it. the key to my file will be "Users/eu-west-1:eu-west-1:fec78-0000-36b-80bd-8e1c54ce/avatar.PNG"

back in my webapp i use aws-S3 to query the object with the same method i use previously

async function S3getObject (BucketName, KeyName) {
    var params = {
      Bucket: BucketName,
      Key: KeyName
    }
    var s3 = new AWS.S3({
      apiVersion: '2006-03-01'
    })
    const data = (await (s3.getObject(params).promise()))

    return data
  }

And here comes the drama..... i get the promise return as an error enter image description here

I'm struggling and have been stuck for a while.

would appreciate a little help.

Thanks a lot

CodePudding user response:

I get it myself. I was close put missed an element in the policy.

I added a list object in my policy, now everything is fine

{
            "Sid": "ListYourObjects",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": [
                "arn:aws:s3:::faascloudplatform"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "Users/${cognito-identity.amazonaws.com:sub}"
                    ]
                }
            }
        }
  • Related