Tag: Cognito


Caching Amazon Cognito Identity IDs

by Norm Johanson | on | in .NET | Permalink | Comments |  Share

Amazon Cognito is a service that you can use to get AWS credentials to your mobile and desktop applications without embedding them in your code. A few months ago, we added a credentials provider for Cognito. In version 2.3.14 of the AWS SDK for .NET, we updated the credentials provider to support caching the identity ID that Cognito creates.

Caching IDs is really useful for mobile and desktop applications where you don’t want to require users to authenticate but need to remember the user for each run of the application. For example, if you have a game whose scores you want to store in Amazon S3, you can use the identity ID as the object key in S3. Then, in future runs of the game, you can use the identity ID to get the scores back from S3. To get the current identity ID, call the GetIdentityId method on the credentials provider. You can also use the identity ID in the AWS Identity and Access Management (IAM) role that Cognito is using to restrict access to only the current user’s score. Below is a policy that shows how to use the Cognito identity ID. In the policy, the variable ${cognito-identity.amazonaws.com:sub} is used. When the policy is evaluated, ${cognito-identity.amazonaws.com:sub} is replaced with the current user’s identity ID.

{
    "Version" : "2012-10-17",
    "Statement" : [
        {
            "Sid" : "1",
            "Effect" : "Allow",
            "Action" : [
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource" : "*"
        },
        {
            "Sid" : "2",
            "Effect" : "Allow",
            "Action" : ["s3:PutObject", "s3:GetObject"]
            "Resource" : "arn:aws:s3:::my-game-scores-bucket/scores/${cognito-identity.amazonaws.com:sub}.json"
        }
    ]
}

In the Windows Phone and Windows Store version of the SDK, caching is controlled by the IdentityIdCacheMode property on Amazon.CognitoIdentity.CognitoAWSCredentials. By default, this property is set to LocalSettings, which means the identity ID will be cached local to just the device. Windows.Storage.ApplicationData.Current.LocalSettings is used to cache the identity ID. It can also be set to RoamingSettings, which means the identity ID will be stored in Windows.Storage.ApplicationData.Current.RoamingSettings, and the Windows Runtime will sync data stored in this collection to other devices where the user is logged in. To turn off caching, set IdentityIdCacheMode to None.

To enable caching for the .NET 3.5 and 4.5 versions of the SDK, you need to extend the Amazon.CognitoIdentity.CognitoAWSCredentials class and implement the GetCachedIdentityId, CacheIdentityId, and ClearIdentityCache methods.

Amazon Cognito Credentials Provider

by Norm Johanson | on | in .NET | Permalink | Comments |  Share

Amazon Cognito helps you create unique identifiers for your end users that are kept consistent across devices and platforms. Cognito also delivers temporary, limited-privilege credentials to your app to access AWS resources. With Amazon Cognito, your app can support unauthenticated guest users as well as users authenticated through a identity provider, such as Facebook, Google, Login with Amazon or with developer authenticated identity providers.

Version 2.3.1.0 of AWS SDK for .NET has added Amazon.CognitoIdentity.CognitoAWSCredentials, a credentials object that uses Cognito and the Security Token Service to retrieve credentials in order to make AWS calls.

The first step in setting up CognitoAWSCredentials is to create an ”identity pool”. (An identity pool is a store of user identity information specific to your account. The information is retrievable across client platforms, devices, and operating systems, so that if a user starts using the app on a phone and later switches to a tablet, the persisted app information is still available for that user.) You can create a new identity pool from the Amazon Cognito management console. If you are using the console, it will also provide you the other pieces of information we will need:

  • Your account number: this is a 12-digit number, such as 123456789012, that is unique to your account.
  • The unauthenticated role ARN: this is a role that unauthenticated users will assume. For instance, this role can provide read-only permissions to your data.
  • The authenticated role ARN: authenticated users will assume this role. This role can have more extensive permissions to your data.

 

Here’s a simple code sample illustrating how this information is used to set up CognitoAWSCredentials, which can then be used to make a call to Amazon S3 as an unauthenticated user.

CognitoAWSCredentials credentials = new CognitoAWSCredentials(
    accountId,        // account number
    identityPoolId,   // identity pool id
    unAuthRoleArn,    // role for unauthenticated users
    null,             // role for authenticated users, not set
    region);
using (var s3Client = new AmazonS3Client(credentials))
{
    s3Client.ListBuckets();
}

 

As you can see, we are able to make calls with just a minimum amount of data required to authenticate the user. User permissions are controlled by the role, so you are free to configure access as you see fit.

The next example shows how you can start using AWS as an unauthenticated user, then authenticate through Facebook and update the credentials to use Facebook credentials. Using this approach, you can grant different capabilities to authenticated users via the authenticated role. For instance, you might have a Windows Phone application that permits users to view content anonymously, but allows them to post if they are logged on with one or more of the configured providers.

CognitoAWSCredentials credentials = new CognitoAWSCredentials(
    accountId, identityPoolId,
    unAuthRoleArn,    // role for unauthenticated users
    authRoleArn,      // role for authenticated users
    region);
using (var s3Client = new AmazonS3Client(credentials))
{
    // Initial use will be unauthenticated
    s3Client.ListBuckets();
    
    // Authenticate user through Facebook
    string facebookToken = GetFacebookAuthToken();
    
    // Add Facebook login to credentials. This will clear the current AWS credentials
    // and new AWS credentials using the authenticated role will be retrieved.
    credentials.AddLogin("graph.facebook.com", facebookAccessToken);

    // This call will be performed with the authenticated role and credentials
    s3Client.ListBuckets();
}

This new credentials object provides even more functionality if used with the AmazonCognitoSyncClient that is part of the .NET SDK: if you are using both AmazonCognitoSyncClient and CognitoAWSCredentials, you don’t have to specify the IdentityPoolId and IdentityId properties when making calls with the AmazonCognitoSyncClient. These properties are automatically filled in from CognitoAWSCredentials. Our final example illustrates this, as well as an event that notifies us whenever the IdentityId for CognitoAWSCredentials changes. (The IdentityId can change in some cases, such as going from an unauthenticated user to an authenticated one.)

CognitoAWSCredentials credentials = GetCognitoAWSCredentials();

// Log identity changes
credentials.IdentityChangedEvent += (sender, args) =>
{
    Console.WriteLine("Identity changed: [{0}] => [{1}]", args.OldIdentityId, args.NewIdentityId);
};

using(var syncClient = new AmazonCognitoSyncClient(credentials))
{
    var result = syncClient.ListRecords(new ListRecordsRequest
    {
        DatasetName = datasetName
        // No need to specify these properties
        //IdentityId = "...",
        //IdentityPoolId = "..."        
    });
}

For more information on Amazon Cognito, including use-cases and sample policies, visit the official Amazon Cognito page or the Cognito section of the Mobile Development blog.