Access Amazon Web Services using Amazon Cognito for Mobile Applications and NetIQ Access Manager 4.1

Access Amazon Web Services using Amazon Cognito for Mobile Applications and NetIQ Access Manager 4.1

Author: Sureshkumar Thangavel



Usecase


 
You are writing a mobile or web application to access Amazon Web Services like Cognito Synchronized Storage, S3, Amazon DynoDB etc. Also, you need to handle Identities of your application and store the application state or access services unique per Identity in the Amazon Web Service. In this case, you want to delegate handling of Identities or don't want to provide custom login code and delegate authentication mechanism to NetIQ Access Manager. You want to have a light weight technology to handle the Identities and integrate well with Web Technologies like RESTful services and Oauth2 as well as Mobile.

This solution uses Amazon Cognito Service from Amazon. Amazon Cognito is a easy to use service that simplifies mobile development for storing mobile user data in AWS cloud without writing any back-end code or any infrastructure. The data usually will be application's preference of the user, game state data, application state or the whole application itself. More details can be found here. This is the recommended way for accessing AWS services from mobile.

Amazon Web Services allows to integrate with third party Identity Providers using OpenID Connect. With this, you can get a token from NetIQ Access Manager, and exchange that for a Security Credential from Amazon IAM service. You can then use that credentials for accessing other Amazon Services. With this way, you can leverage your investment in your existing Identity technologies but access resources hosted on Amazon Webservices.

The following diagram shows the overall flow when your end user accesses your application and reading data stored on Amazon Web services.
aws-service-nam


  1. The user accesses the application. Application checks whether it has token for the user. If not, it opens a stock browser and initiates OpenID Connect flow.




  2. As part of OpenID Connect flow, the user enters his credential through browser if he has not already logged into Access Manager through browser.




  3. Access Manager provides ID Token as response to the application via browser.




  4. The client application exchanges the ID Token to Amazon STS. Amazon IAM STS has to be setup with a trust to Access Manager.




  5. STS validates the ID Token and provides a Temporary Security Credential back to application. This credential is associated with the user




  6. Applications uses the temporary credentials to invoke Amazon Services.




Pre-requisites





  1. Access Manager 4.1 with external internet pointing interface




  2. Amazon Developer Account with Cognito Service enabled




Preparing Access Manager for AWS


 

  1. Open Administration Console of NetIQ Access Manager

    1. Navigate to the Identity Provider

    2. Enable “Oauth and OpenID Connect”. Refer detailed instructions.

    3. Navigate to Identity Servers -> OAuth and OpenID Connect -> Global Settings

    4. change Issuer to “namnetiq.in/nidp/oauth/nam” without https in front. AWS Cognito sdk don't accept ':' chars in on one of its api. That's the reason for this change.

    5. Refer this full documentation for getting Oauth2 and OpenID Connect ready for development by following other pre-requisites mentioned in the documentation here. (More importantly extend the User schema for attribute to store Authorization Grant information. AWS integration does not require any special scope or permissions)



  2. Amazon IAM requires the OpenID Connect Metadata to have certain feilds. In 4.1, couple of fields are missing in metadata. You can use the attached jar for development. Next release will have this fixed in the product itself.





    1. Take a backup of /opt/novell/nam/idp/webapps/nidp/WEB-INF/lib/nam-oauth-config-rest.jar




    2. Deploy attached jar to /opt/novell/nam/idp/webapps/nidp/WEB-INF/lib. nam-oauth-config-rest.jar




    3. Restart idp “/etc/init.d/novell-idp restart”





Creating a client for AWS Application


 
First the application to be developed should be registered with Access Manager. Refer the NetIQ Access Manger 4.1 Documentation for how to register a client application.

Give the following Values in the client registration screen

  1. Navigate to https://nam.com/nidp/ and login with developer credentials

  2. Click Applications -> My Applications -> Register New Client

  3. Enter following values


    1. Client Name: Implicit Sample




    2. Client Type: Native




    3. Redirect URI: x-nam-aws-sample://aws




    4. Grants Required: Implicit




    5. Token Types: ID Token, Access Token




    6. ID Token Signed Response Algorith: RS256




    7. ID Token Encrypted Response Algorithm: None






  4. Click OK




  5. Click on the row of previously created client




  6. Make a note of Client ID and Client Secret.




    1. Client ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

    2. Client Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx





Adding Access Manager as Identity Provider in Amazon


 
Amazon STS has to trust NetIQ Access Manager before it issues temporary credentials to your application. For this, NetIQ Access Manager Instance has to be integrated with Amazon through Amazon Developer console. You need to enter only the NetIQ Access Manager OpenID Connect Metadata URL & Client ID you created above. Then the whole setup is automagically created. You can refer to this link for detailed setup at the Amazon side.

  1. Open Identity and Access Management console of Amazon Developer Console https://console.aws.amazon.com/iam/.

  2. Navigate to Identity Providers -> Create Provider

  3. Enter following values

    1. Provider Type : OpenID Connect

    2. Provider URL: https://your_idp_url/nidp/oauth/nam (Note: Amazon will look for metadata at https://your_idp_url/nidp/oauth/nam/.well-known/openid-configuration. Also, 4.1 has few fields missing in metadata, refer Pre-requisites section to replace one of the given jar with the attached jar in Identity Provider)

    3. Audience: <Client ID received in previous section>amazon1

    4. Click Next Step

    5. Verify the details in the next page and click Create.amazon2




Creating Identity Pool for storing application Identities


 
Next, we need to create a pool for the identities that will be authenticated through your application. Amazon segregates the users into pools. Each pool will have a set of users and their data. For more information refer this link

  1. Open AWS Cognito Developer Console at https://console.aws.amazon.com/cognito/home

  2. Click “Create new Identity Pool” if you already don't have any pool

  3. Enter values

    1. Identity Pool Name: NAM Identity Pool

    2. Leave “Enable access to unauthenticated identities” unchecked if you don't want users to use your application without authenticating

    3. In the Authentication Providers, select “OpenID” and check the check box next to the Identity Provider that you imported in the previous section.amazon3

    4. Click Next

    5. In the next screen, you need to give roles to users authenticating through your application. This will help you to restrict what Amazon resources the users will be able to use through your application. You can choose to create a new role or use existing role. Make sure that the roles policy document contains sections as below




{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*"
],
"Resource": [
"*"
]
}
]
}

The screen shot will look like this

amazon4


    1. Click Allow

    2. You will be taken to “Sample Code”. We'll use the code in this screen in later sections.



Writing Client Code to access Services


 
Now, you can start writing mobile application code. The mobile application will now integrate with NetIQ Access Manager for authenticating the users. The mobile application then will use this identity to access Amazon Web Services.

Getting ID Token from Access Manager


 
To access the Amazon Web Services, you require to have Amazon Credentials. You can get an Identity Token from NetIQ Access Manager and use that to get the Amazon Credentials. You can use one of the two methods to get the Identity Token from Access Manager. You can either use Authorization Code flow or Implicit Code flow. ID tokens are not issued in other OAuth2.0 flows.

My previous article describes how to get ID Token using Implicit flow from a mobile application. The link can be found here. This application uses System's stock browser to initiate Implicit Flow. There are many variations to this method like using embedded browser. The sample is for Android with Java code.

Please refer to NetIQ Access Manager REST API guide also for endpoints and request & response parameters for various flows. You can use this for a reference if you want to develop on iOS.

NetIQ Access Manager 4.1 does not support requesting additional claims in ID Token in this release. But this will be added in future releases. For now, if you want to get additional Identity Attributes for storing them in Amazon User data in case, you can use UserInfo endpoint in NetIQ Access Manager 4.1. This method is also explained in the previous article.

Accessing Amazon Services


 
Once you have got the ID Token and required claims of the user as mentioned in the previous section, you can use that to exchange for amazon credentials and invoke amazon APIs. The steps in this section is mainly for using Amazon Cognito Java SDK for Android. But the same concepts can be applied to iOS library and iOS application as well.

The first step involves adding necessary dependencies to your project for using Cognito library. Here is my app/build.gradle file

apply plugin: 'com.android.application'

android {
compileSdkVersion 21
buildToolsVersion "21.1.2"

packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
}

defaultConfig {
applicationId "mobile.sample.oauth.nam.netiq.com.nam_aws_sample"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])



compile 'com.android.support:appcompat-v7:22.0.0'
compile 'com.amazonaws:aws-android-sdk-cognito:2.2.1'
compile 'com.google.oauth-client:google-oauth-client:1.20.0'
compile 'com.fasterxml.jackson.core:jackson-core:2.5.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.5.3'
compile 'com.google.http-client:google-http-client:1.20.0'
compile 'com.google.http-client:google-http-client-jackson2:1.20.0'
compile 'org.bitbucket.b_c:jose4j:0.4.1'

}

Next in your activity where you want to use Amazon Cognito storage sync, initialize the credential Provider
	          final Context ctx = this; // inside Activity.OnCreate
// Initialize the Amazon Cognito credentials provider
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
ctx, // Context
"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", // Identity Pool ID
Regions.US_EAST_1 // Region
);
credentialsProvider.clearCredentials();
credentialsProvider.clear();

You can get the “Identity Pool ID” from the amazon Cognito management console.

 

Next we need to integrate the credentials received in the previous section using NetIQ Access Manager with the client library.
                Map<String, String> logins = new HashMap<String, String>();
logins.put(“nam.com/nidp/oauth/nam”, idToken);
credentialsProvider.setLogins(logins);

Note that, the first parameter to logins.put should match the “issuer” of ID Token and also the “issuer” in OpenID Connect metadata of NetIQ Access Manager. You can check the issuer value from https://yournam.com/nidp/oauth/nam/.well-known/openid-configuration.

By setting the above map, Amazon can provision the user on demand. Whenever you save a data using this cognito client with this credential, Amazon maps a unique ID for this user uniquely matching the “sub” of ID Token.

You can get the temporary credentials that Amazon Cognito created by invoking this API.
                String identityId = credentialsProvider.getIdentityId();
Log.d(LOG_ID, "my ID is " + identityId);

If you have not received any exception in previous steps, you can start sychronizing user specific data such as user's preferences, personalization, game state, etc in Amazon Storage. The following code snipper creates a data set called “myDataset” with the values for “subject”, “access_count”, “email”. The access_count is increased each time the application is launched with the same user context. You can save any data.
                // Initialize the Cognito Sync client
CognitoSyncManager syncClient = new CognitoSyncManager(
ctx,
Regions.US_EAST_1, // Region
credentialsProvider);

// Create a record in a dataset and synchronize with the server
Dataset dataset = syncClient.openOrCreateDataset("myDataset");
String oldSubject = dataset.get("subject");
String access_count = dataset.get("access_count");
final int count = access_count == null ? 0 : Integer.parseInt(access_count);
if (oldSubject == null || !oldSubject.equals(fsubject)) {
dataset.put("subject", fsubject);
dataset.put("email", email);
}
dataset.put("access_count", String.valueOf(count+1));

You can view the user's data that's saved on Amazon using Amazon Cognito using “Identity Browser” in Amazon Cognito Management Console https://console.aws.amazon.com/cognito/identities.

Navigate to “Identity Pool: nam_idpool” -> Identity Browser.

This screen will list all the unique temporary ids created for provisioned Identities from third parties. You can click on any of the identities to see what values the application have saved. For example the above code have saved the following.

amazon5
Labels (2)

DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Top Contributors
Version history
Revision #:
5 of 5
Last update:
‎2020-01-31 22:10
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.