Amazon Cognito/IAM and Facebook login, part two

This is the second part of the post which shows how to integrate Amazon Cognito and IAM (Identity & Access Management) and Facebook login. The first is here and is a series of screenshots.

This post will briefly explain how to set up a local environment and develop and test it before deploying it to Amazon S3. This and the first guide relies in part heavily on Serverless Single Page Apps by Ben Rady which you can buy from pragprog.com.

I use OS X and macports for package management on the command line so the examples provided are on this platform. Seasoned Linux- and BSD-users knows the difference and will apply appropriately.

I have very little experience with cygwin and mingw.

When you start developing the app you can do so on your local machine. It’s faster to test changes on local code instead of having to upload it to S3 first, easier to install extra programs etc.

AmazonFBauthentication42

At the bottom of the page you specify the ‘Site URL’ you are using. When I developed the app on my local machine my URL was ‘https://localhost/’. I had plain http to begin with but got some error messages that said I was mixing http and https so I changed it to encrypted https.

You may want to install a webserver. OS X ships with apache but sometimes Apple is slow updating apache, sometimes you want a custom-build apache server. I use nginx which can be installed issuing the command

$ sudo port install nginx

The default installation path is /opt/local and the configuration file is located at /opt/local/etc/nginx/nginx.conf.

After nginx is installted you will create a local snakeoil certificate. I followed this guide. When you have the certificates copy them to this location or choose your own path and edit nginx.conf and add or change these lines accordingly



# HTTPS server
server {
  listen 443 ssl;
  server_name localhost;

  ssl_certificate /opt/local/etc/openssl/certs/selfserve.crt;
  ssl_certificate_key /opt/local/etc/openssl/private/selfserve.key;

  location /cielo {
    root /Users/claus/devel/;
    index index.html;
  }
}

Don’t forget to reload the nginx configuration, this can be done with

$ sudo nginx -s reload

I have created a github repo with some example code which you are welcome to clone and modify. The poolId in utils.js

var poolId = 'eu-west-1:82de430e-6f53-4d84-90fa-509d6b6775d3';

is from the example code in ‘Federated Identities’ in the Cognito console.

AmazonFBauthentication06

The poolId is paired with the appId that was entered when the pool was created.

AmazonFBauthentication26

The appToken in the javascript code and the ‘Site URL’ shown in the first image is used by Facebook to grant your app access. So I conveniently changed the URL before publishing the code. Otherwise the code can easily be cloned and run from any local machine and possibly be abused.

var appToken = '860675960666169|00_5tkwxjsUj_u6P1-U1IXjj9mE';

The appToken consists of your appId and a token separated with a pipe symbol (|). You can generate the token using curl. Run the following command on the command line.

$ curl 'https://graph.facebook.com/oauth/access_token?client_id=APPID&client_secret=CLIENTSECRET&grant_type=client_credentials'

The output can look like

access_token=860675960666169|00_5tkwxjsUj_u6P1-U1IXjj9mE%

Copy the string between the equal- and percent-sign and paste it into your own code. I think I got the curl-command from a stackoverflow thread. You can read this blog for additional information.

Don’t reveal the app secret to others.

Create a bucket on S3. Bucket names are unique so if you have a domain add this. Descend down to the folder where the code is and issue this command

$ aws s3 sync . s3://your.bucket.name

Before you can use the aws command you have to install and configure it. Ben Rady explains the procedure in great detail in his book.

After the code is synchronized to S3 enable ‘Static Website Hosting’ on the right hand side and specify the ‘Index Document’. In this case it’s index.html.

AmazonFBauthentication43

Grant Everyone access to index.html and click Save. Repeat the process for other files where needed.

AmazonFBauthentication44

There is a publicly available link to index.html. The URL could be used but only the hostname is used by Facebook to restrict where the app can be run from. So anything after the forward slash after the hostname is ignored. Which means that you can’t rely on this to prevent others from impersonating you.

Instead you can use another service provided by Amazon called CloudFront. This also has the advantage they can provide encrypted https to your S3 bucket.

Ivan Kusalic have some advise if you use CloudFront with a third-party certificate. I did not have some of the problems Ivan mentions but maybe the service have matured since he tried it.

Creating a CloudFront service is easy. I feel that Amazon have put great efforts into the creation of services as effortless as they can become. Click on ‘Create Distribution’.

AmazonFBauthentication46

Click ‘Get Started’ in the Web section.

AmazonFBauthentication45

In ‘Origin Domain Name’ a list with your buckets will be available. Select the bucket you created above. If you only want encrypted https select ‘HTTPS Only’ in ‘Viewer Protocol Policy’. The other settings can be left as they are. I have selected ‘Use only US and Europe’ in ‘Price Class’ in the section ‘Distribution Settings’ since performance is not a concern. The section is in the same window but further down and thus not visible. Just scroll down and you’ll see it.

AmazonFBauthentication47

Click ‘Create Distribution’. It will take a while before it is ready. I went to bed when I created the distribution and it was finished when I woke up again but I doubt it takes all night.

Copy the domain name to the site URL in your Facebook app settings and you should be all set.

This app only show the content of a table. In a later update I’ll add the possibility to enter some information and update the table. Till them take care.

Amazon Cognito/IAM and Facebook login, part one

This guide will show you how to create services at Amazon and pair them with a Facebook login in order to access resources within the rich Amazon ecosystem.

A later post will show basic javascript code so you can login and retrieve information from a DynamoDB table.

I recommend reading ‘Serverless Single Page Apps’ by Ben Rady. You can buy the book in print and/or pdf from https://pragprog.com/book/brapps/serverless-single-page-apps. This gives a nice introduction to Amazon’s web-services.

Perform the following steps to create the required amazon services in order to authenticate using Facebook credentials.

Open a browser at https://developers.facebook.com and login/register and add a new app. In the dashboard the App Id will be used when creating a pool at Amazon.

Open a browser at https://aws.amazon.com/ and login/register.

Click on ‘Cognito, User Identity and App Data Synchronization’ in the third column in the section Mobile Services.

AmazonFBauthentication01

Click on ‘Managed Federated Identities’ in the next step.

AmazonFBauthentication02

Click on ‘Create new identity pool’.

AmazonFBauthentication03

Enter the name of the new pool in ‘Identity pool name’. Here I name it Generic Pool. Do not enable ‘Unauthenticated identities’ unless you provide anonymous access. Select the Facebook tab in ‘Authenticated providers’ and enter your App Id provided by Facebook and click ‘Create Pool’.

AmazonFBauthentication04

Click Allow to grant access to your ressource.

AmazonFBauthentication05

When access have been granted some example code shows how to access the ressource, in this case javascript.

AmazonFBauthentication06

Use the Dashboard to see information about the pool.

AmazonFBauthentication07

Open ‘Identity & Access Management’ in ‘Security & Identity’ in the second column.

AmazonFBauthentication01

Click on Roles in the left column and your newly created roles appear.

AmazonFBauthentication08

Clicking on Cognito_GenericPoolUnauth_Role shows that no policies are attached to this role. Since we don’t want to open up for anonymous access we just leave it as it is.

AmazonFBauthentication10

We want to allow Cognito_GenericPoolAuth_Role access to DynamoDB so click on ‘Attach Policy’ in ‘Managed Policies’ in the Permissions tab.

AmazonFBauthentication11

Select AmazonDynamoDBFullAccess and click ‘Attach Policy’ to allow this role to use DynamoDB.

AmazonFBauthentication12

The policy is then shown in ‘Managed Policies’.

AmazonFBauthentication13

Time to create tables in DynamoDB. Open https://eu-west-1.console.aws.amazon.com/dynamodb/home?region=eu-west-1 and click on ‘Create table’.

AmazonFBauthentication14

In this example I create a table with a partition- and sort-key.

AmazonFBauthentication15

When the table is created you can click on the Items tab on the right side and create an item.

AmazonFBauthentication17

Clicking on the ‘Create item’ button brings up a modal window. Enter the partition key and sort key and then append any desired fields.

AmazonFBauthentication16

I’ve inserted one record which we will retrieve later.

Click on the ‘Access control’ tab on the right hand side and select Facebook as the ‘Identity provider’. Select all Actions just beneath and ‘All attributes’ in ‘Allowed attributes’ and click ‘Create policy’. This will bring up the policy on the right which you can copy and paste into an editor and we’ll use it later when create a custom policy.

AmazonFBauthentication18

Lets create a custom policy that allow access our newly created table. Click on ‘Create policy’.

AmazonFBauthentication19

Select ‘Create Your Own Policy’.

AmazonFBauthentication20

Give it a descriptive name and description and paste the policy copied from above and click ‘Validate Policy’.

AmazonFBauthentication21

Click ‘Create Policy’ to save the policy.

AmazonFBauthentication22

Add the newly created policy to a role. Select Role from the left side and ‘Create New Role’.

AmazonFBauthentication23

Enter a name for the role and ‘Next Step’.

AmazonFBauthentication24

Select ‘Role for Identity Provider Access’ and then ‘Grant access to web identity providers’.

AmazonFBauthentication25

Select Facebook from ‘Identity Provider’ and enter the Application ID that is assigned by Facebook when the application was created and click on ‘Next Step’.

AmazonFBauthentication26

Click on ‘Next Step’.

AmazonFBauthentication27

Then you are asked to attach a policy. Select the one you just created and click ‘Next Step’. You may have to search for the policy in the filter input field.

AmazonFBauthentication28

Review and click ‘Create Role’.

AmazonFBauthentication29

Click on Groups in the left pane and ‘Create New Group’.

AmazonFBauthentication30

Enter the name of the group in ‘Group Name’ and click ‘Next Step’.

AmazonFBauthentication31

Enter the name of the policy you just created in the search field and select the policy and click ‘Next Step’.

AmazonFBauthentication32

Review and click ‘Create Group’.

AmazonFBauthentication33

Click on the group you just created.

AmazonFBauthentication34

A message notifies that this group has no users. Click on ‘Add Users to Group’.

AmazonFBauthentication35

Select the user and click ‘Add Users’.

AmazonFBauthentication36

The group is created, the policy is attached, the user is added to the group.

AmazonFBauthentication37

Now is the time to put the App ID assigned by Facebook and the pool ID by Amazon to some use. We will build a simple page in html and javascript to connect to the Amazon Cognito service using the javascript SDK from Facebook and Amazon. Don’t forget to change the invalid Facebook App ID in this example from 9012345678 to the real one given by Facebook.

AmazonFBauthentication38

When clicking on the Facebook button a new window will appear with a username and password dialog. Enter your credentials. The first time you open a new app from Facebook it asks for permission to access your public profile, which is basically your name, email-address if any and user-id. Click Okay to continue.

AmazonFBauthentication39

If permission is granted a new window will show what the app then can do. This can post on Facebook on your behalf and you can limit who will receive these messages. This app won’t post any messages. Click Okay.

AmazonFBauthentication40

When you are all set this is what the page looks like.

AmazonFBauthentication41

 

In a upcoming post I will link to the code I have and how you move it to Amazon’s S3 storage and serve it from there. As you can see the app is run from localhost. This will change when the code is copied to S3.

I hope you have enjoyed this post. It was originally intended as an reminder to myself but I figured others might find it useful as well.

Take care.