The sample application below authenticates users using web identity federation and Facebook login. After logging in, the user will get temporary AWS credentials and assume the pre-specified IAM (AWS Identity and Access Management) role whose policy allows uploading and listing objects in Amazon S3.

This guide is designed to walk readers through integrating an AWS-backed JavaScript web application with a third-party identity provider, setting up properly scoped permissions for federated access to AWS APIs, and basic usage of the AWS SDK for JavaScript.

CORS needs to be configured on the Amazon S3 bucket to be accessed directly from JavaScript in the browser.
  1. Navigate to the Amazon S3 console.
  2. Choose an existing bucket or create a new bucket if desired. Note the bucket name and bucket region for later use in the application.
  3. Click the Properties tab, open the Permissions section, and click Edit CORS Configuration.
  4. Copy the below XML into the text box and click Save.

<?xml version="1.0" encoding="UTF-8"?>

<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01">

   <CORSRule>

      <AllowedOrigin>*</AllowedOrigin>

      <AllowedMethod>GET</AllowedMethod>

      <AllowedMethod>PUT</AllowedMethod>

      <AllowedMethod>POST</AllowedMethod>

      <AllowedMethod>DELETE</AllowedMethod>

      <AllowedHeader>*</AllowedHeader>

   </CORSRule>

</CORSConfiguration>

To enable Facebook login with web identity federation, you need to create an application at the Facebook developer page and note the App ID. Make sure the Facebook app's settings allow login from the domain where you'll host the sample app. This is done by going to the Settings section in the Facebook app page and specifying the Site URL as the domain where your html will be hosted (e.g. http://localhost/ if testing locally or https://YOUR-BUCKET-NAME.s3.amazonaws.com/ if hosting the html on S3).

  1. Go to the Policies section of the IAM console and click Create Policy -> Create Your Own Policy.
  2. Name your policy (e.g. JavaScriptSample), copy the JSON policy below to the Policy Document text box, and replace the two instances of YOUR_BUCKET_NAME with your actual bucket name, and click Create Policy.
  3. Now go to the Roles section of the IAM console and click Create New Role.
  4. Name your role and select Role for Identity Provider Access -> Grant access to web identity providers.
  5. Select Facebook and type in your Facebook App ID.
  6. Click Next Step on Verify Role Trust.
  7. On the Attach Policy step, select the policy you just created, and click Next Step, then Create Role on the next page.

{

   "Version": "2012-10-17",

   "Statement": [

      {

         "Action": [

            "s3:PutObject",

            "s3:PutObjectAcl"

         ],

         "Resource": [

            "arn:aws:s3:::YOUR_BUCKET_NAME/facebook-${graph.facebook.com:id}/*"

         ],

         "Effect": "Allow"

      },

      {

         "Action": [

            "s3:ListBucket"

         ],

         "Resource": [

            "arn:aws:s3:::YOUR_BUCKET_NAME"

         ],

         "Effect": "Allow",

         "Condition": {

            "StringEquals": {

               "s3:prefix": "facebook-${graph.facebook.com:id}"

            }

         }

      }

   ]

}

Before you can run the example, you need to replace 'YOUR_APP_ID', 'YOUR_ROLE_ARN''YOUR_BUCKET_NAME', and 'YOUR_BUCKET_REGION' with appropriate values. Region takes the form of 'us-east-1' (US Standard), 'us-west-2' (Oregon), etc. The ARN (Amazon Resource Name) of your IAM role can be found in the IAM console by selecting your role and opening the Summary tab.

<!DOCTYPE html>

<html>

<head>

    <title>AWS SDK for JavaScript - Sample Application</title>

    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>

</head>

<body>

    <input type="file" id="file-chooser" />

    <button id="upload-button" style="display:none">Upload to S3</button>

    <div id="results"></div>

    <div id="fb-root"></div>

    <script type="text/javascript">

        var appId = 'YOUR_APP_ID';

        var roleArn = 'YOUR_ROLE_ARN';

        var bucketName = 'YOUR_BUCKET_NAME';

        AWS.config.region = 'YOUR_BUCKET_REGION';

        var fbUserId;

        var bucket = new AWS.S3({

            params: {

                Bucket: bucketName

            }

        });

        var fileChooser = document.getElementById('file-chooser');

        var button = document.getElementById('upload-button');

        var results = document.getElementById('results');

        button.addEventListener('click', function () {

            var file = fileChooser.files[0];

            if (file) {

                results.innerHTML = '';

                //Object key will be facebook-USERID#/FILE_NAME

                var objKey = 'facebook-' + fbUserId + '/' + file.name;

                var params = {

                    Key: objKey,

                    ContentType: file.type,

                    Body: file,

                    ACL: 'public-read'

                };

                bucket.putObject(params, function (err, data) {

                    if (err) {

                        results.innerHTML = 'ERROR: ' + err;

                    } else {

                        listObjs();

                    }

                });

            } else {

                results.innerHTML = 'Nothing to upload.';

            }

        }, false);

        function listObjs() {

            var prefix = 'facebook-' + fbUserId;

            bucket.listObjects({

                Prefix: prefix

            }, function (err, data) {

                if (err) {

                    results.innerHTML = 'ERROR: ' + err;

                } else {

                    var objKeys = "";

                    data.Contents.forEach(function (obj) {

                        objKeys += obj.Key + "<br>";

                    });

                    results.innerHTML = objKeys;

                }

            });

        }

        /*!

         * Login to your application using Facebook.

         * Uses the Facebook SDK for JavaScript available here:

         * https://developers.facebook.com/docs/javascript/gettingstarted/

         */

        window.fbAsyncInit = function () {

            FB.init({

                appId: appId

            });

            FB.login(function (response) {

                bucket.config.credentials = new AWS.WebIdentityCredentials({

                    ProviderId: 'graph.facebook.com',

                    RoleArn: roleArn,

                    WebIdentityToken: response.authResponse.accessToken

                });

                fbUserId = response.authResponse.userID;

                button.style.display = 'block';

            });

        };

         // Load the Facebook SDK asynchronously

        (function (d, s, id) {

            var js, fjs = d.getElementsByTagName(s)[0];

            if (d.getElementById(id)) {

                return;

            }

            js = d.createElement(s);

            js.id = id;

            js.src = "//connect.facebook.net/en_US/all.js";

            fjs.parentNode.insertBefore(js, fjs);

        }(document, 'script', 'facebook-jssdk'));

    </script>

</body>

</html>

http://YOUR_DOMAIN/sample.html

This sample application is designed to show you how to:

  • Use the AWS Web Identity Federation and Facebook login to authenticate users.
  • Assign user-specific write permissions at the prefix level with IAM role policy so that users can't overwrite or change other users' objects.
  • Instantiate an Amazon Simple Storage Service (Amazon S3) client.
  • Use <input type="file" /> tag that calls the browser's native file interface, and upload the chosen file to an Amazon S3 bucket, with 'public-read' permissions.

If you have trouble getting set up or have other feedback about this sample, let us know on the AWS SDK for JavaScript forum.

For in-depth user guides, API documentation, developer forums, and other developer resources, see the AWS SDK for JavaScript in the Browser page.