How to make unauthenticated access working with Am

2020-05-06 11:31发布

  1. I created Federated Identity
  2. Enabled Unauthenticated Access to it with checkbox
  3. Created role associated with this identity and gave it Administrator Access, so it should have all permissions
  4. Then I add this code to upload files to AWS S3, it works with Access / Secret keys, that I wouldn't like to expose to UI, but it doesn't work with Cognito

To be clear, everything is client JavaScript and I want everything serverless, so I don't have my own API and not going to implement custom access provider on my end. I only want to prevent exposing my access and secret key in UI.

/**
   * Handle file upload with Amazon S3 bucket
   * @param id - record ID in local DB
   * @param doc - file to be uploaded, taken from event.target.files
   * @param done - callback to call after upload
   */
  public sendFileToAws(id: number, doc: File, done: Function) {

    // @Todo : Move to config

    let pointer = this;

    aws.config.region = pointer.awsRegion;
    aws.config.credentials = new aws.CognitoIdentityCredentials({
      IdentityPoolId: 'us-east-1:e48af67b-c315-47ca-b816-000000000000',
      RoleArn: 'arn:aws:iam::000000000000:role/GognitoSuperUserRole',
      AccountId: '000000000000'
    });

    //aws.config.update({
    //  region: pointer.awsRegion,
    //  accessKeyId: pointer.awsAccessKey,
    //  secretAccessKey: pointer.awsSecretKey
    //});

    let server = new aws.S3({ params: { Bucket: pointer.awsStorageName } });
    let directory = pointer.getDocumentDirectory() + '/' + id + '-' + doc.name;

    let params = {
      Key: directory,
      ContentType: doc.type,
      Body: doc,
      Bucket: pointer.awsStorageName,
      ACL: pointer.awsPermission
    };

    server.upload(params, (e, data) => {
      done(e, data);
    });
  }

It returns me the following error :

<ErrorResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
  <Error>
    <Type>Sender</Type>
    <Code>AccessDenied</Code>
    <Message>Not authorized to perform sts:AssumeRoleWithWebIdentity</Message>
  </Error>
  <RequestId>28b768a5-8f30-11e7-a7bf-4b5038235cb8</RequestId>
</ErrorResponse>

1条回答
虎瘦雄心在
2楼-- · 2020-05-06 11:36

I'm also working on a front end Typescript application that uses both Authenticated and Unauthenticated identities from Cognito.

For unauthenticated identities, my flow looks like this:

  • Create a new identity in the identity pool using CognitoIdentity.getId().
  • Create a credentials object using the identity pool id and new identity id only.

That code looks like this:

var cognitoidentity = new AWS.CognitoIdentity();
var params = {
    IdentityPoolId: 'us-east-1:bxxxxxx-cxxx-4xxx-8xxx-9xxxxxxxxxxx'
};

// tslint:disable-next-line:no-any
cognitoidentity.getId(params, function(err: any, data: any) {
    if (err) {
        console.log(err, err.stack); // an error occurred
    } else {

        AWS.config.credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: 'us-east-1:bxxxxxxx-cxxx-4xxx-8xxx-9xxxxxxxxxxx',
            IdentityId: data.IdentityId
        });

        // access AWS resources
    }
});

This will result in your app getting temporary IAM credentials (access key, secret key, session token) that are used to access back end resources.

The role assumed when you use these keys will be the role you configured in your Identity Pool settings:

enter image description here

This way you don't have to expose the IAM role name to the browser, either. AWS will simply assume the correct role based on the IAM keys.

Happy Hacking!

查看更多
登录 后发表回答