Wednesday, February 19, 2014

AWS Web Identity Federation for Mobile Apps - Facebook (1 of 3 series)

Imagine that you have a mobile app that needs access to AWS resources. (Or it might be a web app that uses client script; the concepts presented here are the same.) The app might be a game that runs on a phone and stores the player and score information in an Amazon S3 bucket or an Amazon DynamoDB table. Because the app needs to be able to distinguish individual users, users cannot be anonymous.

Since it is not a good idea to distribute long-term credentials, you want to build the app such that it requests temporary security credentials using web identity federation. This lets you create an app that authenticates users using existing identity providers like a) Facebook, b) Login with Amazon, c) Google.

Using any of these providers can simplify the development and management of your app. Instead of providing custom sign-in logic and having to manage user login information (either in a custom system or as IAM users), your app can rely on well-known and secure sign-in protocols that many users already have access to. Because you can trade a token from the identity provider for temporary security credentials, you don't have to distribute any credentials with the app, and you don't need to manage the process of rotating the credentials. You can find more info here.

This is a three part series, where each part will cover one identity provider. I will cover Facebook in this blog.

 Prerequisites and Helper function

·         Sign up for AWS and get the AccessKey & SecretKey. You can find the info about AWS Account and Access Keys here.
·         You have Visual Studio installed, I used Visual Studio 2013. Although I did not test it, earlier version should work.
·         Install AWS SDK for .Net from here. Follow the “Getting Started” instructions from there.

Mobile App with Third Party Sign-In

The following figure shows a simplified flow for how this might work, using Login with Amazon as the identity provider. For Step 1, the app can also invoke Facebook or Google, but that's not shown here.




The following details enable this scenario:
·         Developer has registered the mobile app with different identity providers, who have assigned an app ID to the app.
·         The mobile app includes logic to invoke the appropriate identity provider (depending on which sign-in option the user chooses) and to get back a token from the provider.
·         The app can call AssumeRoleWithWebIdentity without using any AWS security credentials. The call includes the token received from the provider previously.
·         AWS STS is able to verify that the token passed from the app is valid and then returns temporary security credentials to the app. The mobile app's permissions to access AWS are established by the role that the app assumes.

Create a Role

This is the role that a Facebook authenticated user will assume. The role is associated with two things a) trust policy – who can assume this role and b) access policy – what permission does the assumed user have.

C# code below creates a role. Normally, this is manually created once. I chose to write C# code because it is handy for automation. This role can be assumed by any authenticated Facebook user. The user only has access to their specific key which is located under “federationbucket/Facebook/”. Code below is slightly complicated because the same code is used for Google/Amazon login as well.

    identityProvider = "Facebook";
    providerURL = "graph.facebook.com";
    providerAppIdName = "app_id";
    providerUserIdName = "id";

    //identity provider specific AppId is loaded from app.config
    //  The key names are like FacebookProviderAppId. 
    //  GoogleProviderAppId, AmazonProviderAppId
    providerAppId = ConfigurationManager.AppSettings[identityProvider + "ProviderAppId"];

    // Since the string is passed String.Format, '{' and '}' has to be escaped.
    // Policy document specifies who can invoke AssumeRoleWithWebIdentity
    string trustPolicyTemplate = @"{{
            ""Version"": ""2012-10-17"",
            ""Statement"": [
                {{
                        ""Effect"": ""Allow"",
                        ""Principal"": {{ ""Federated"": ""{1}"" }},
                        ""Action"": ""sts:AssumeRoleWithWebIdentity"",
                        ""Condition"": {{
                            ""StringEquals"": {{""{1}:{2}"": ""{3}""}}
                        }}
                }}
            ]
        }}";

    // Defines what permissions to grant when AssumeRoleWithWebIdentity is called
    string accessPolicyTemplate = @"{{
                ""Version"": ""2012-10-17"",
                ""Statement"": [
                {{
                        ""Effect"":""Allow"",
                        ""Action"":[""s3:GetObject"", ""s3:PutObject"", ""s3:DeleteObject""],
                        ""Resource"": [
                                ""arn:aws:s3:::federationtestbucket/{0}/${{{1}:{4}}}"",
                                ""arn:aws:s3:::federationtestbucket/{0}/${{{1}:{4}}}/*""
                        ]
                    }}
                ]
            }}";

    CreateRoleRequest createRoleRequest = new CreateRoleRequest
    {
        RoleName = "federationtestrole",
        AssumeRolePolicyDocument = string.Format(trustPolicyTemplate, identityProvider,                               providerURL, providerAppIdName, providerAppId)
    };
    Console.WriteLine("\nTrust Policy Document:\n{0}\n",                                                             createRoleRequest.AssumeRolePolicyDocument);
    CreateRoleResponse createRoleResponse = iamClient.CreateRole(createRoleRequest);

    PutRolePolicyRequest putRolePolicyRequest = new PutRolePolicyRequest
    {
        PolicyName = "federationtestrole-rolepolicy",
        RoleName = "federationtestrole",
        PolicyDocument = string.Format(accessPolicyTemplate, identityProvider, providerURL,                                         providerAppIdName, providerAppId, providerUserIdName)

    };
    Console.WriteLine("\nAccess Policy Document (Permissions):\n{0}\n",                                                             putRolePolicyRequest.PolicyDocument);
    PutRolePolicyResponse putRolePolicyResponse =                                                                                   iamClient.PutRolePolicy(putRolePolicyRequest);

    System.Threading.Thread.Sleep(5000);
    AmazonS3Config config = new AmazonS3Config
    {
        ServiceURL = "s3.amazonaws.com",
        RegionEndpoint = Amazon.RegionEndpoint.USEast1
    };

Above code assumes an app.config file to contain the following values.
     <appSettings>
        <add key="AWSAccessKey" value="YOUR_ACCESS_KEY_A134" />
        <add key="AWSSecretKey" value="YOUR_SECRET_KEY_HERE_SECRET_KEY_HEREndgN" />
        <add key="AWSRegion" value="us-east-1" />
        <add key="FacebookProviderAppId" value="123456789012345" />
    </appSettings>

Trust Policy document produced by the above code:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { "Federated": "graph.facebook.com" },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {"graph.facebook.com:app_id": "123456789012345"}
            }
        }
    ]
}

Access Policy document (permissions) produced by the above code:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect":"Allow",
            "Action":["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
            "Resource": [
                "arn:aws:s3:::federationtestbucket/Facebook/${graph.facebook.com:id}",
                "arn:aws:s3:::federationtestbucket/Facebook/${graph.facebook.com:id}/*"
            ]
        }
    ]
}

Authenticate with Facebook and get the token

The following query is constructed, and a GET action is performed in the browser. It will be redirected to a page where Facebook gets user password/consent. If the authentication succeeds, it will be redirected to the URL specified in the query. The C# code below uses the Forms based WebBrowser control to automate this process.

The query:
    string query = "https://www.facebook.com/dialog/oauth?" +
        string.Format ("client_id={0}&", client_id) +
        "response_type=token&" +
        "redirect_uri=https://www.facebook.com/connect/login_success.html";

The GetToken helper function, does GET operation and retrieves the token from the redirected URL.
    class MyWebBrowser : WebBrowser
    {
        public string CapturedUrl;
        string token;
        public MyWebBrowser(string token)
        {
            this.token = token + "=";
        }

        protected override void OnDocumentCompleted(WebBrowserDocumentCompletedEventArgs e)
        {
            base.OnDocumentCompleted(e);
            string st = e.Url.ToString();
            if (st.Contains(token))
            {
                this.Navigate("about:blank"); // hack, closing the form is not working                        this.CapturedUrl = st;
                Console.WriteLine("Captured: {0}", st);
            }
            else if (st == "about:blank")
            {
                ((Form)this.Parent).Close();
            }
        }
    }

    string GetToken(string token, string url)
    {
        Form f = new Form();
        MyWebBrowser wb = new MyWebBrowser(token);
        wb.Dock = DockStyle.Fill;
        f.Controls.Add(wb);
        wb.Navigate(url);
        f.WindowState = FormWindowState.Maximized;
        f.ShowDialog();

        string st = wb.CapturedUrl;
        f.Dispose();

        if (st == null)
            throw new Exception("Oops! Error getting the token");

        int index = st.IndexOfAny(new char[] { '?', '#' });
        st = index < 0 ? "" : st.Substring(index + 1);
        NameValueCollection pairs = HttpUtility.ParseQueryString(st);

        string tokenValue = pairs[token];
        Console.WriteLine("TOKEN={0}, Value={1}", token, tokenValue);
        return tokenValue;
    }

Get Temporary Credentials with AssumeRoleWithWebIdentity

Key concept to grasp here is, you start with anonymous AWS credentials, pass the Facebook token and get the temporary credentials. This is important because the mobile app user will not have any AWS credentials.
    // role - ARN for the role to assume
    // client_id of the Facebook app
    public AssumeRoleWithWebIdentityResponse GetTemporaryCredentialUsingFacebook(string client_id, string role)
    {
        string query = "https://www.facebook.com/dialog/oauth?" +
            string.Format ("client_id={0}&", client_id) +
            "response_type=token&" +
            "redirect_uri=https://www.facebook.com/connect/login_success.html";

        AssumeRoleWithWebIdentityRequest assumeRoleWithWebIdentityRequest = 
                                                     new AssumeRoleWithWebIdentityRequest
        {
            ProviderId = "graph.facebook.com",
            WebIdentityToken = GetToken("access_token", query),
            RoleArn = role,
        };

        return GetAssumeRoleWithWebIdentityResponse (assumeRoleWithWebIdentityRequest);
    }

    AssumeRoleWithWebIdentityResponse GetAssumeRoleWithWebIdentityResponse(
                          AssumeRoleWithWebIdentityRequest assumeRoleWithWebIdentityRequest)
    {
        // Start with Anonymous AWS Credentials and get temporary credentials.
        var stsClient = new AmazonSecurityTokenServiceClient(new AnonymousAWSCredentials());
        assumeRoleWithWebIdentityRequest.DurationSeconds = 3600;
        assumeRoleWithWebIdentityRequest.RoleSessionName = "MySession";
        return stsClient.AssumeRoleWithWebIdentity(assumeRoleWithWebIdentityRequest);
    }

Using temporary credentials to make an update to S3 bucket

    S3Test s3Test = new S3Test();
    s3Test.CreateS3Bucket("federationtestbucket",
        identityProvider + "/"
        assumeRoleWithWebIdentityResponse.SubjectFromWebIdentityToken,
        assumeRoleWithWebIdentityResponse.Credentials, config);
    class S3Test
    {
        public void CreateS3Bucket(string bucketName, string key, 
                            Credentials credentials, AmazonS3Config config)
        {
            var s3Client = new AmazonS3Client(credentials.AccessKeyId, 
                            credentials.SecretAccessKey, credentials.SessionToken, config);

            string content = "Hello World2!";

            // Put an object in the user's "folder".
            s3Client.PutObject(new PutObjectRequest
            {
                BucketName = bucketName,
                Key = key,
                ContentBody = content
            });

            Console.WriteLine("Updated key={0} with content={1}", key, content);
        }
    }

Delete the role created

Again, you will not be doing the following in your mobile app. This is only for automation. Also,  note that you need real AWS credentials to create and delete the role.
    DeleteRolePolicyResponse deleteRolePolicyResponse = iamClient.DeleteRolePolicy(
    new DeleteRolePolicyRequest
    {
        PolicyName = "federationtestrole-rolepolicy",
        RoleName = "federationtestrole"
    });

    DeleteRoleResponse deleteRoleResponse = iamClient.DeleteRole(new DeleteRoleRequest
    {
        RoleName = "federationtestrole"
    });

Registering an app with Facebook

Create an app at https://developers.facebook.com/ by providing a name and category. Once the app is created, note down the 15 digit App Id, we will need it later.
Facebook exposed a nice way to manually get the token, very handy during development. Also, find the Web Identity Federation link from the references, this is very helpful as you develop/debug your app.

References

5.       Facebook login workflow

You can find the code under “AWS\AWS CSharp Test” folder at https://github.com/padisetty/Samples.

Explore & Enjoy!

/Siva

39 comments:

  1. I am always searching online for articles that can help me. There is obviously a lot to know about this. I think you made some good points in Features also. Keep working, great job
    buy facebook photo likes

    ReplyDelete
  2. Admiring the time and effort you put into your blog and detailed information you offer!..
    http://buyfblikescheap.com/buy-real-facebook-likes/

    ReplyDelete
  3. Friends on Facebook seem to follow a trend whereby they generally like most of their friends likes. The idea has Facebook now suggesting fan pages for other friends to like. find this

    ReplyDelete
  4. People want to know who you are first before they will join any business you're involved with. Be honest with who you are in your profile. Tell people your likes, interests, and hobbies. Facebook hacken gratis

    ReplyDelete
  5. Well Said, you have furnished the right information that will be useful to anyone at all time. Thanks for sharing your Ideas.

    Aws Online Training

    ReplyDelete
  6. I so far have sold 3 cell phones utilizing two distinct sites that I have found through an examination site and I've not profited but rather enough to cover a month to month shop or a night out. http://webbiscuits.net

    ReplyDelete
  7. For wholesale distributors of fast-moving consumer goods, FMCG, (TARGET), who’s sales reps and/or customers need to place remote orders on portable, wireless computing devices (FOR) employing mobile order management software that is fast, reliable, powerful, flexible, easy-to-use, 100% “native” with scores of trade-specific features and full back-office integration (DIFF), containing “core logic” developed and supported by the one enterprise software company, Ai2, with the utmost industry knowledge, ability and longevity (RTB)
    mobile ordering

    ReplyDelete
  8. A look at the steps to put in place to ensure that mobile security is guaranteed will be helpful for many users of the mobile devices.visit electricalshop.net

    ReplyDelete
  9. The rental cost is typically 5% to 10% of the cost of the video game for up to 7 days worth of play. Domino QQ

    ReplyDelete
  10. I suspect that the War on Used Games is nothing more than a money grab by developers, upset that they're unable to cash in on a very lucrative market. Agen Bola

    ReplyDelete
  11. The Facebook likes are an indicator of how many people actually know about the brand - whether it is a new product, service, movie, singer, artist and so on. buy Facebook likes

    ReplyDelete
  12. I’ve been searching for some decent stuff on the subject and haven't had any luck up until this point, You just got a new biggest fan!.. facebook to mp4

    ReplyDelete
  13. This has caused some genuine issues as shoppers aren't imbeciles and the poor incentive for cash being given by some of these huge brands is keeping the development of the business dormant.pop over to these guys

    ReplyDelete
  14. Cla Safflower Oil As we get more seasoned we frequently get busier, and before we know it, end up in the prime of our lives and pressing a couple of additional pounds.
    http://www.drozhealthblog.com/cla-safflower-oil/

    ReplyDelete
  15. Biogenic Xr critiques for tablets will give you a clean photograph of tablets so that you can decide if a specific one will paintings fine for you.
    http://www.healthprograme.com/biogenic-xr-reviews/

    ReplyDelete
  16. Trojan is a type of virus which hacker can send to the person whose fb password he intends to hack. Once active, trojan can send any data from the device of the victim including facebook password, messages etc to the hacker www.BluePortal.org

    ReplyDelete
  17. Testro T3 it is p training all the one of a kind motions, actions and manipulations to get the very fine outcomes.
    http://www.drozhealthblog.com/testro-t3-uk/

    ReplyDelete
  18. Testx Core Peyronie's malady is dynamic and can in the end prompt male ineptitude or even the powerlessness to have . These normally methods can be utilized to lessen even the most serious instances of penile bends normally.
    http://www.usadrugguide.com/testx-core-review/

    ReplyDelete
  19. Not exclusively is it a well known area for social connections yet in addition it is turning into a savagely aggressive promoting apparatus. BRSM.IO

    ReplyDelete
  20. This is a wonderful post.thanks for sharing puppy bark box

    ReplyDelete
  21. Vedda Blood Sugar Remedy Weight reduction/Muscle Building: Regularly individuals experiencing Type diabetes are additionally overweight and can turn around the indications of diabetes basically by losing some muscle versus fat, practicing and eating right.
    http://www.drozhealthblog.com/vedda-blood-sugar-remedy/

    ReplyDelete
  22. CLA Safflower Oil Be that as it may, in spite of the express disappointment of these techniques, the industry keeps on creating the same, or comparative, 'fixes' and marking them over again.
    http://xtrfact.com/cla-safflower-oil/

    ReplyDelete
  23. CLA Safflower Oil This outcomes in a huge and fast weight drop. Be that as it may, this isn't economical and not suggested for the long run, since dinner substitution shakes can just furnish you with constrained supplements.
    http://xtrfact.com/cla-safflower-oil/

    ReplyDelete
  24. <a href=" https://clashroyalhacktool.com/clash-royale-cheats/”> Clash royale cheats</a>
    I was perusing your article and thought about whether you had considered making a digital book on this subject. You're composing would offer it quick. You have a great deal of composing ability.

    ReplyDelete
  25. Dermagen IQ They invigorate the generation of auxiliary skin proteins required to keep the skin smooth, firm and wrinkle free. They likewise support and feed the skin with all the required supplements and hydration to make it solid and solid from inside.
    http://www.drozhealthblog.com/dermagen-iq/

    ReplyDelete
  26. Rapiture Muscle Builder Go to muscle building exercises If you are an apprentice in muscle fabricating, your work out schedules Rapiture Muscle for Spain to construct muscle ought to include warm up activities to help shape the center muscles that fill in as the establishment for your future body manufactured.
    http://xtrfact.com/rapiture-muscle-builder/

    ReplyDelete
  27. You can also set Facebook up to require approval of a log in. When someone (hopefully you) attempts to log in a text message with a verification code is sent to you. The person attempting to log in has to enter the verification code in order to continue.www.gotodiveshack.com

    ReplyDelete
  28. D BAL Max forming your body into a more strong constitution, which each man needs At the point when an individual means.
    http://xtrfact.com/d-bal-max-review/

    ReplyDelete
  29. This is genuinely an awesome read for me. I have bookmarked it and I am anticipating perusing new articles. Keep doing awesome!
    Web Development

    ReplyDelete
  30. Xtrfact practice bulimia, anorexia, and different bulimias), falsehood, a sloppiness, or an absence of inspiration.
    http://xtrfact.com/

    ReplyDelete
  31. Wow, What a Excellent post. I really found this to much informatics. It is what i was searching for.I would like to suggest you that please keep sharing such type of info.Thanks The Sims Mobile Hack

    ReplyDelete
  32. Pure CBD Oil What sicknesses and diseases does this item help with There are varieties of restorative uses related with medicinal cannabis.
    http://www.drozhealthblog.com/pure-cbd-oil/

    ReplyDelete
  33. Nitridex As per fanatics of this male hair evacuation style expelling all the hair from your backside.
    http://supplementdigestdog.com/nitridex/

    ReplyDelete
  34. Zylix Plus even though procreation is the evolutionary intention of intercourse, that doesn't imply you need .
    http://www.drozhealthblog.com/zylix-plus/

    ReplyDelete

  35. Respecting the time and exertion you put into your site and point by point data you offer!..
    Web Development

    ReplyDelete
  36. Before starting out, it's worth writing down your list of reasons for creating a mobile app or mobile website for your business. Think about what you would like to achieve and what you would like your product to do.
    ShowBox APK Download

    ReplyDelete