16
© Copyright IBM Corporation 2016 Trademarks Enhance mobile application security with Bluemix Mobile Services, Part 1 Page 1 of 16 Enhance mobile application security with Bluemix Mobile Services, Part 1 Secure client-side authentication with Mobile Client Access and Facebook Joshua A. Alger ([email protected]) Software developer IBM David R. Cariello ([email protected]) Software developer IBM 04 May 2016 Use Bluemix Mobile Services and Facebook to secure mobile application data for Android and iOS. IBM's Bluemix® Mobile Services package includes a collection of back-end services that allow you to quickly build and scale iOS, Android, and hybrid mobile applications. In this two-part tutorial, you'll learn how to utilize two core Bluemix Mobile Services—Mobile Client Access and IBM Push Notifications—to create a secure cross-platform mobile application. In this first part, you'll quickly create a mobile back end on Bluemix and connect it to a cross- platform mobile application built using StrongLoop and Node.js. You'll then be able to extend the mobile app for secure client-side authentication using Bluemix's Mobile Client Access service and Facebook. In Part 2, you'll extend and modify the Bluemix back end so that you can securely send broadcast push messages to registered devices using custom Node.js code.

Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

Embed Size (px)

Citation preview

Page 1: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

© Copyright IBM Corporation 2016 TrademarksEnhance mobile application security with Bluemix MobileServices, Part 1

Page 1 of 16

Enhance mobile application security with BluemixMobile Services, Part 1Secure client-side authentication with Mobile Client Access andFacebook

Joshua A. Alger ([email protected])Software developerIBM

David R. Cariello ([email protected])Software developerIBM

04 May 2016

Use Bluemix Mobile Services and Facebook to secure mobile application data for Android andiOS.

IBM's Bluemix® Mobile Services package includes a collection of back-end services that allow youto quickly build and scale iOS, Android, and hybrid mobile applications. In this two-part tutorial,you'll learn how to utilize two core Bluemix Mobile Services—Mobile Client Access and IBM PushNotifications—to create a secure cross-platform mobile application.

In this first part, you'll quickly create a mobile back end on Bluemix and connect it to a cross-platform mobile application built using StrongLoop and Node.js. You'll then be able to extend themobile app for secure client-side authentication using Bluemix's Mobile Client Access service andFacebook. In Part 2, you'll extend and modify the Bluemix back end so that you can securely sendbroadcast push messages to registered devices using custom Node.js code.

Page 2: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 2 of 16

We've provided application code for both Android and iOS, to demonstrate how to use the mobileclient SDK to consume these mobile services.

Get the code

What you'll need

For your basic development environment you'll need the following:

• A Bluemix account• A Facebook application• A Cloud Foundry CLI

For the iOS mobile app you'll need:

• Xcode• CocoaPods• An iOS device• A valid APNs-enabled development environment and artifacts (see Configuring iOS and

APNs)

For the Android mobile app you'll need:

• An Android development environment (we recommend Android Studio)• A GCM sender ID and API key (see instructions on Bluemix)

This tutorial assumes you are familiar with programming for iOS and Android mobile apps.

Page 3: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

ibm.com/developerWorks/ developerWorks®

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 3 of 16

Step 1. Create the mobile backend app on Bluemix

In the Bluemix catalog, you'll find the MobileFirst Services Starter boilerplate, which contains thecore services for building mobile applications on Bluemix. You can leverage this boilerplate and theprovided services to greatly ease the process of developing a secure mobile application.

Begin by creating an instance of the MobileFirst Services Starter boilerplate:

• In the Boilerplates section of the Bluemix catalog, click MobileFirst Services Starter:

• Enter a unique name and host for your mobile backend and click Create:

• After the provisioning is complete you'll be taken to a Start Coding page, which willprovide resources for deploying your app with the Cloud Foundry (CF) command-lineinterface. Click the Overview tab on the left-hand side of the page. You'll see a top-level

Page 4: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 4 of 16

view of the Node.js runtime and service tiles for your newly deployed Bluemix application:

• Click the Mobile Options link in the top-right corner of the screen. Here you'llfind your appRoute and appGUID. Keep this screen open in your browser;you'll need these parameters when you configure the mobile client application:

Step 2. Interact with your Bluemix mobile app

Using the browser of your choice, navigate to your mobile application's appRoute(<Application_Name>.mybluemix.net). You'll find a web app built with Node.js and StrongLoopthat you can use to create, update, and view a set of list items. Familiarize yourself with the webapplication by clicking these prompts.

Page 5: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

ibm.com/developerWorks/ developerWorks®

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 5 of 16

You'll note that the application's delete function doesn't yet work. The boilerplate Node.js codeuses Mobile Client Access (MCA) to protect the delete endpoint. You'll have an opportunity tocomplete this function using the mobile client SDK later in the tutorial.

Bluemix and StrongLoop

When you build a Bluemix application with StrongLoop, it creates and stores API Referencesat http://Your_Application_Name.mybluemix.net/explorer/#!/Item. Use the StrongLoop APIExplorer, shown below, to familiarize yourself with the RESTful APIs for the for the backend webapplication. You'll utilize some of these later in this tutorial.

You can also access the source code for the bms-helloTodo-strongloop boilerplate application onGitHub.

Page 6: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 6 of 16

READ: Get started with StrongLoop

Step 3. Get, configure, and run the demo

At this stage, you've developed a backend web application using StrongLoop and Node.js andcreated a few list items against an unprotected MCA instance, meaning no login is required. Next,you'll get, configure, and run the iOS or Android mobile app.

1. Find the source code for the sample Android and iOS mobile applications in our GitHubrepository.

2. Use the Git command-line interface to clone the repository locally, save it to your computerusing the GitHub Desktop app, or download the .zip directly.

3. Configure and initialize the helloTodoAdvanced application for iOS or Android. (Note:Please stick to the configuration steps in the README documents for now. We'll completeand explain the remainder of the steps later in this tutorial.)

4. Run the application for the first time on your desired platform:• In Xcode, click Product > Run.• In Android Studio, click Run and select a device.

When you run the Android or iOS mobile application for the first time, your client will initialize withyour Bluemix instance and attempt to pull down the group of list items that you've created. If you'resuccessful, the data you entered via the web interface will be displayed on the client app's mainpage. Here's a screenshot of the iOS app:

Here's the Android app:

Page 7: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

ibm.com/developerWorks/ developerWorks®

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 7 of 16

Notes about the demoBecause MCA allows access using the mobile client SDK, you can edit, create, and even deleteany of the to-do tasks (just hold the item on Android or swipe left on iOS).

You aren't required to log in to the application because you haven't yet enabled an authenticationmechanism. The MCA configuration is all you need to securely access data.

Don't worry if you see a few errors in the logs! They're nonfatal and will be resolved when youenable IBM Push Notifications in Part 2.

How the client SDK communicates with Node.jsAt the beginning of this tutorial you used StrongLoop to automatically create simple CRUD APIendpoints. All the CRUD data interactions for the demo app are subsequently done via RESTrequests to your Bluemix StrongLoop-enabled Node.js application, using the mobile client SDK. Inthe code snippets below, you can see how the SDK provides the necessary APIs for easy RESTfulinteractions.

Warning: If you experience an "invalid_grant" error when running this application, you'llneed to reset/wipe your simulator or uninstall the application. This can happen if the clientapplication caches an authorizationHeader from a previous MCA instance. When theapplication attempts to authenticate against the new MCA instance it will use the cachedheader, causing the error.

Listing 1 shows the IMFResourceRequest for iOS.

Page 8: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 8 of 16

Listing 1. iOS: ViewController.m- (void) createItem: (NSString*) itemText{ NSString *restAPIURL = [NSString stringWithFormat:@"%@/api/Items",_backendRoute]; IMFResourceRequest* request = [IMFResourceRequest requestWithPath:restAPIURL]; NSDictionary *jsonDict = [NSDictionary dictionaryWithObjectsAndKeys: itemText, @"text", @"false", @"isDone", nil]; NSData *data = [NSJSONSerialization dataWithJSONObject:jsonDict options:NSJSONWritingPrettyPrinted error:nil]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:data]; [request sendWithCompletionHandler:^(IMFResponse *response, NSError *error) { if (error != nil) { NSLog(@"createItem failed with error: %@",error); } else { NSLog(@"Item created successfully"); } [self listItems]; }];

}

Listing 2 shows the Request for Android, sending item information to the API endpoint for itemcreation.

Listing 2. Android: MainActivity.java// Create JSON for new TodoItem, id should be 0 for new itemsString json = "{\"text\":\"" + name + "\",\"isDone\":false,\"id\":0}";

// Create POST request with the Bluemix Mobile Services SDK and set HTTP headers so Bluemix knows what to expect in the requestRequest request = new Request(bmsClient.getBluemixAppRoute() + "/api/Items", Request.POST);

HashMap headers = new HashMap();List<String> contentType = new ArrayList<>();contentType.add("application/json");List<String> accept = new ArrayList<>();accept.add("Application/json");

headers.put("Content-Type", contentType);headers.put("Accept", accept);

request.setHeaders(headers);

request.send(getApplicationContext(), json, new ResponseListener() { // On success, update local list with new TodoItem @Override public void onSuccess(Response response) { Log.i(TAG, "Item " + name + " created successfully");

loadList(); }

// On failure, log errors @Override public void onFailure(Response response, Throwable throwable, JSONObject extendedInfo) { String errorMessage = "";

if (response != null) { errorMessage += response.toString() + "\n";

Page 9: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

ibm.com/developerWorks/ developerWorks®

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 9 of 16

}

if (throwable != null) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); throwable.printStackTrace(pw); errorMessage += "THROWN" + sw.toString() + "\n"; }

if (extendedInfo != null){ errorMessage += "EXTENDED_INFO" + extendedInfo.toString() + "\n"; }

if (errorMessage.isEmpty()) errorMessage = "Request Failed With Unknown Error.";

Log.e(TAG, "addTodo failed with error: " + errorMessage); }});

You'll notice the data interaction requests all hit the https://<Your_Application_Name>.mybluemix.net/api/Items endpoint, allowing you to appropriatelyreact to any HTTP response. You always want to be in sync with the cloud data, so when yousuccessfully create an item, make sure to GET the remote list data from our Node.js cloud server.

Next we'll show you how to use Bluemix Mobile Services to secure your mobile application data.

Step 4. Configure Facebook authenticationNote: You may only configure one authentication method for the application. You mustchoose between Google, Facebook, or custom authentication, as they are mutuallyexclusive. In this case, we've elected to use Facebook authentication.

You can configure MCA to use Facebook authentication to better secure your application data,by giving each user a unique identity. In this section you'll first create and configure a Facebookapplication using Facebook's Developer site, then configure your MCA instance to utilize theFacebook app as an authentication mechanism.

Set up your Facebook application

If you've already created a Facebook application you can skip the next steps; just make sure thatthe settings for your app match the settings described below.

1. Create the Facebook application using the instructions from the Facebook's Developer site.If you need help, follow the instructions in "Obtaining a Facebook application ID from theFacebook Developer Portal."

• Configurations for iOS: Add the desired platform (iOS) and bundleID ("com.ibm.helloTodoAdvanced") to your Facebook application:

Page 10: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 10 of 16

Notethat we recommend using an APNs-enabled bundle ID. It will be required whenconfiguring push notifications later in the tutorial.

• Configurations for Android: Add the Google Play PackageName ("com.ibm.helloTodoAdvanced") and class name("com.ibm.helloTodoAdvanced.MainActivity") for the demo:

Notethat the Google Play Package Name and Class Name must be identical to the abovescreenshot to successfully run the Android version of the example application. FollowSteps 5 through 9 in the listed documentation to get the correct Key Hash for yourdevelopment environment.

2. After you've configured and created your Facebook application, you must provide theconfigurations to your MCA instance on Bluemix. Navigate back to your Bluemix applicationand click the Mobile Client Access service to open the MCA dashboard.

Page 11: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

ibm.com/developerWorks/ developerWorks®

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 11 of 16

3. Click SET UP AUTHENTICATION and choose Facebook:

4. Add the Application ID to the User Authentication for Facebook:

Great! You now have set up Facebook authentication on your mobile backend application.

Configure client-side authenticationNext, you will configure the client-side helloTodoAdvanced application for Facebook authentication.

For iOS:

1. Update the Info.plist file with your Facebook application ID and display name. You can getboth from the Facebook developer console.

2. Update URL Types > Item 0 > URL Schemes > Item 0. Update Item 0 using your client IDfrom the Facebook developer console; for example: fb1581349575427190.

For Android:

1. Navigate to the strings.xml file, in the Android\helloTodoAdvanced\bluelist\app\src\main\res\values\ directory. Replace Your_Facebook_App_Id with the appID from the applicationyou created.

2. Verify that your Google Play package name in your FacebookappID is com.ibm.helloTodoAdvanced and that your class name iscom.ibm.helloTodoAdvanced.MainActivity.

Run the applicationTry running helloTodoAdvanced to see how the changes you've made affect the application. Noticethat the application now requires Facebook authentication before it will display the list item data.

Page 12: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 12 of 16

Log in with your Facebook account (only public profile information is required). After successfullogin you'll be able to see and interact with the list data. The first screenshot below shows theFacebook login page:

And here's the application with a to-do list item shown:

Page 13: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

ibm.com/developerWorks/ developerWorks®

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 13 of 16

Client-side configuration detailsFor more information about using Facebook as an identity provider, see "Enabling Facebookauthentication in iOS apps."

You've successfully set up and configured your mobile application for Facebook authentication.We'll conclude Part 1 with a closer look at the client-side code that enabled us to use Facebook asan authentication mechanism with MCA.

iOS config

In iOS, you perform the client-side configuration in AppDelegate.m. You can see more informationabout the code at "Enabling Facebook authentication in iOS apps."

In the ViewController.m, you use the obtainAuthorizationHeaderWithCompletionHandler API callto kick off the authentication process and obtain the authorization token from the MCA instance.On a successful authentication, you obtain an authorization header, which the mobile client SDKautomatically includes with outbound REST requests to protected resources, as shown in Listing 3.

Page 14: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 14 of 16

Listing 3. iOS ViewController.m-(void)obtainAuthorizationToken{ IMFAuthorizationManager *authManager = [IMFAuthorizationManager sharedInstance]; [authManager obtainAuthorizationHeaderWithCompletionHandler:^(IMFResponse *response, NSError *error) { if (error != nil) { NSLog(@"%@",error); } else { NSLog(@"You have obtained the authorization token from Bluemix successfully."); //Register for Push once Login to MCA is successful [self registerForPush];[self listItems]; } }];}

This function is called as the main view loads, so the authentication process begins as theapplication starts. You can then only pull down the list items once the user has been successfullyauthenticated. As you can see in the code, you kick off the push registration process following asuccessful login. You'll learn more about the push registration process in Part 2.

Android config

In MainActivity.java, you'll see the initAuth() function within onResume(). This ensures that everytime the app enters the foreground, it will obtain an authorization header to validate against MCA.

The obtainAuthorizationHeader call is what issues the authentication request that kicks offFacebook authentication from the device. A new intent is created for the login prompt, enabled bythe FacebookAuthorization SDK and AndroidManifest.xml changes.

For more information about how to configure and enable this login see "Enabling Facebookauthentication in Android apps."

Upon a successful login the user is able to see the application data. Under the hood,MainActivity.java implements the ResponseListener interface, which requires the threeoverridden functions in order to securely handshake with your Bluemix MCA instance:onActivityResult(), onSuccess(), and onFailure().

Assuming that the Facebook login succeeds, your next step will be to load the list data from yourNode.js app and register the app and device with the IBM Push Notifications service. We'll set uppush notifications in Part 2. For now just study the code.

Listing 4. Android MainActivity.javaonSuccess()

@Overridepublic void onSuccess(Response response) { Log.i(TAG,"Successfully authenticated against MCA: " + response.getResponseText());

// Register for push notifications and show data now that the user is authenticated registerForPush(); loadList();}

Page 15: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

ibm.com/developerWorks/ developerWorks®

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 15 of 16

If a request from MCA Facebook authorization fails, the local list is wiped to protect the data. Notethat any of the parameters can be null depending on the type of failure. Listing 5 shows the outputof an authorization failure.

Listing 5. Android MainActivity.java

onFailure()

@Overridepublic void onFailure(Response response, Throwable throwable, JSONObject extendedInfo) {

if(!mTodoItemAdapter.isEmpty()){ Log.i(TAG, "clearing list data since authentication failed"); mTodoItemList.clear(); mTodoItemAdapter.notifyDataSetChanged(); }

String errorMessage = "";

// Check for 404s and unknown host exception since this is the first request made by the app if (response != null) { if (response.getStatus() == 404) { errorMessage += "Application Route not found at:\n" + BMSClient.getInstance().getBluemixAppRoute() + "\nPlease verify your Application Route and rebuild the app."; } else { errorMessage += response.toString() + "\n"; } }

// Be sure to check for null pointers, any of the above parameters may be null depending on the failure. if (throwable != null) { if (throwable.getClass().equals(UnknownHostException.class)) { errorMessage = "Unable to access Bluemix host!\nPlease verify internet connectivity and try again."; } else { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); throwable.printStackTrace(pw); errorMessage += "THROWN" + sw.toString() + "\n"; } }

if (extendedInfo != null){ errorMessage += "EXTENDED_INFO" + extendedInfo.toString() + "\n"; }

if (errorMessage.isEmpty()) errorMessage = "Request Failed With Unknown Error.";

Log.e(TAG, "Failed to authenticate against MCA: " + errorMessage);

}

The protected onActivityResult function enables interaction between MCA and yourMainActivity, needed for proper authentication.

Page 16: Mo mobile-application-security-bluemix-mobile-services-1-trs-pdf

developerWorks® ibm.com/developerWorks/

Enhance mobile application security with Bluemix MobileServices, Part 1

Page 16 of 16

Listing 6. onActivityResult

onActivityResult()

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data);

FacebookAuthenticationManager.getInstance().onActivityResultCalled(requestCode, resultCode, data);}

Note: Be sure to include super.onActivityResult() or else the onSuccess()/onFailure function will be called twice.

In addition to security features, MCA also provides monitoring and analytics for your mobileapplications, including usage statistics and client-side log capture.

Now that you've run the example application successfully a few times, you should be able to seesome of your data in the Monitoring tab of your Bluemix MCA instance.

READ: Bluemix Application Monitoring

Conclusion to Part 1You can leverage the core Bluemix Mobile Services to do more than what we've shown here,including monitoring app usage, capturing tester and live-user experiences, viewing qualitymetrics, and integrating with Node.js to run app logic in the cloud.

In the first half of this tutorial you've set up your development environment using Bluemix MobileServices and the iOS or Android environment of your choice. You've created a web applicationbackend on Bluemix and connected it to a mobile app built with StrongLoop and Node.js. You thenused MCA to configure and enable your mobile app for secure Facebook authentication. In Part2, we'll introduce IBM Push Notifications, which you'll use for secure broadcast push notification inyour Node.js mobile app.

Mobile Services Starter boilerplatehttps://console.ng.bluemix.net/catalog/starters/mobilefirst-services-starter/gives you a head start for developing, deploying, and scaling server-sideJavaScript apps with ease.Mobile Client Accesshttps://console.ng.bluemix.net/catalog/services/mobile-client-access/provides security analytics, secure back-end communications, and userauthentication services.IBM Push Notificationshttps://console.ng.bluemix.net/catalog/services/ibm-push-notifications/lets you send push notifications to Android and iOS devices.RELATED TOPICS: Bluemix Mobile Node.js

© Copyright IBM Corporation 2016(www.ibm.com/legal/copytrade.shtml)Trademarks(www.ibm.com/developerworks/ibm/trademarks/)