Using the OAM Mobile & Social SDK to secure native mobile apps - Part 1 - iOS SDK

Introduction

In this blog post I'll try to demystify a key strategic area for our customers--i.e. securing mobile native apps with Oracle Access Manager using the mobile client SDK. I recently delivered both a session and a HOL (hands on lab) at OOW 2013 here in San Francisco on the same topics and this blog post is an attempt to provide more detail in those areas.

I have planned this post in two parts. In this first part I'll cover client side development using the SDK and in the second part I'll cover the required server side configuration that needs to be performed in conjunction with using the client side SDK.  Also, while this post uses the iOS SDK to secure native iOS apps, the same concepts apply while securing mobile native apps on the android platform for which we released android SDK support with OAM R2PS1 in the middle of this year. I conducted a workshop for our sales consultants then about using the android SDK and maybe I can figure out a way to release those contents here later as well. Finally, all the source code for the sample apps that we will use in this post is available for download along with an attached viewlet that you can download here: https://www.dropbox.com/sh/6tc7vxyn9zn43an/JloXNybqN_

Why use the SDK?

Aside from making your job easier to retrofit your apps with externalizing security to Oracle Access Manager,  the SDK was built to basically help you with automating certain tasks when you're looking to secure your mobile apps specifically:

  • Accessing and sending mobile device context information
  • Managing client side security data (keys, tokens)
  • Single Sign On (Native app - Native app OR  Browser - Native App)
  • Strong Authentication (KBA, OTP)
  • Offline Authentication
  • Social Logins

Developing with the iOS SDK

Invoking Authentication Services

Using the OAM M&S SDK for authentication services listed above is actually quite straightforward and essentially consists of five basic steps that can be divided into two categories:

  1. Methods called on the SDK by the calling application : The calling application invokes three methods on the SDK to perform these three tasks- initialize, setup and authenticate.
  2. Methods called back by the SDK to return control back to the calling application : The calling application implements two methods that are called back by the SDK to return control back to the calling application: for post processing after setup and post processing after authenticate respectively.

We will now use code snippets from the sample AvitekInventory app throughout the blog post to demonstrate using the SDK. 

Initialize

The first step is to create an object of OMMobileSecurityService and initialize the iOS SDK by providing required OAM Mobile and Social server details. This is done by the calling application invoking the initWithProperties:delegate: instance method that returns a MobileSecurityService object initialized using the properties set in a dictionary. 

LoginViewController.h : 


@property (strong,nonatomic) OMMobileSecurityService *mss;

LoginViewController.m: 

oamDelegate = [[AvitekOAMDelegate allocinit];

self.mss = [[OMMobileSecurityService allocinitWithProperties:sdkProps delegate:oamDelegate];

Here, oamDelegate is an instance of AvitekOAMDelegate, the delegate class that implements callback methods that are invoked by the SDK for post processing after setup and authentication respectively. The sdkProps parameter is an NSMutableDictionary object that contains properties that represent OAMMS server side configuration details such as service Domain, application profile and server url.

Setup

Next, the calling program invokes setup on the SDK. 

LoginViewController.m:

[self.mss setup];

The setup method downloads and stores the configured server side security policies and application profile for this app from OAM. The iOS client SDK will not download the application profile from the server on subsequent setup invocations until the ProfileCacheDuration setting defined in the application profile on the server has expired.

The setup invocation is an asynchronous invocation and on completion the iOS client SDK calls the didReceiveApplicationProfile:error: instance method on the delegate which returns an NSDictionary object that contains the application profile details from the server.

AvitekOAMDelegate.m:

- (void)didReceiveApplicationProfile: (NSDictionary *)applicationProfile error: (NSError *)error

Authenticate

Finally, we are ready to start the authentication process.

LoginViewController.m:

authReq = [[OMAuthenticationRequest alloc] init];

[self.mss startAuthenticationProcess:authReq presenterViewController:self];

The startAuthenticationProcess:presenterViewController instance method takes an authentication request (OMAuthenticationRequest) object that represents a custom view and the presenterViewController to display the viewcontroller that collects the user's name and password. If the customized login view properties (kbaView and authView) are not passed with the authentication request object, the SDK will throw a default login and KBA view.  The SDK starts the authentication process with OAM server and calls back the delegate's didFinishAuthentication:error: method when it's done.

AvitekOAMDelegate.m:

- (void)didFinishAuthentication: (OMAuthenticationContext *)context error: (NSError *)error 

LoginViewController.m

// load the next view

retail = [[RetailStoreViewController alloc]init];

retail.mss = self.mss;

[self.navigationController pushViewController:retail animated:true];

 The delegate method returns an OMAuthenticationContext that contains details about the authentication token. On successful authentication, we are now ready --and our sample AvitekInventory app simply loads the next "business login screen" by pushing the RetailStoreViewController on the NavigationController stack.

Offline Authentication 

OAM Mobile & Social added support for offline authentication in R2PS1. Using this feature is easy. This feature requires that first the "Offline Authentication" setting is enabled in the Application Profile in the OAM Admin Console. Next, while starting the authentication process with the SDK using the startAuthenticationProcess:presenterViewController: method above, set a property called 'connectivityMode' on the OMAuthenticationRequest object which accepts values from the enum OMConnectivityMode and provides options to basically authenticate locally with cached credentials either always or only if the server is unreachable or simply allow authentication only with the server and fail if the server is unreachable. 

Single Sign On

I'll describe Single Sign On in this section as it pertains to native mobile apps participating in single sign on. For Mobile SSO to work, an application installed on the mobile device needs to be designated as the Mobile SSO agent app. The other applications on the mobile device that need to authenticate with OAM are considered as client apps that are configured in a circle of trust in the common Service Domain on the OAM server. The Mobile SSO client apps always authenticate via the agent app that serves as a proxy between OAM and themselves. The Mobile SSO client apps get the benefit  of not having to build authentication/KBA, device registration functionality while getting the benefit of mobile single sign on as the SDK utilized by the agent app automatically handles their sessions including the ability to time-out idle sessions, manage global logout and assist with device selective wipe-outs ( if the OAAM Security Handler plugin is selected in the server side configuration).

In our case, AvitekInventory is the agent app and AvitekScheduler is the client app. First, let's look at the client app. From our client app perspective, it uses the SDK in the exact same manner as described in the earlier sections - i.e. it simply invokes initialize, setup and authenticate and implements delegates for postprocessing during setup and during authentication. The difference is that since this app is configured as a client on the OAM server, all authentication requests are automatically sent by the SDK to the agent app which makes the necessary acquisitions (access token, registration handle and user token) on behalf of the client app from the OAM server.

So, the AvitekScheduler's usage of the SDK below should look very familiar and straightforward:

AvitekScheduler

LoginViewController.m:

//initialize and setup

self.mss = [[OMMobileSecurityService alloc] initWithProperties:sdkProps delegate:self];

[self.mss setup];

//authenticate

authReq = [[OMAuthenticationRequest allocinit];

[self.mss startAuthenticationProcess:authReq presenterViewController:self];

//implement delegate for post setup

-(void) didReceiveApplicationProfile: (NSDictionary *)applicationProfile error: (NSError *)error

//implement delegate for post authentication processing; load business logic screen

-(void) didFinishAuthentication: (OMAuthenticationContext *)context error: (NSError *)error

{

...

scheduler = [[SchedulerViewController alloc]init];

scheduler.mss = self.mss;

[self.navigationController pushViewController:scheduler animated:true];

Now, let's look at our AvitekInventory agent app.  

AvitekInventory

LoginViewController.m:

First, we parse the incoming request URL (i.e. from the client app) and populate a dictionary with query parameter name and values using the parseURL:fromApp: method. We then initialize and setup and instance of the SDK for the agent app that will be later used to process SSO requests from the client.

(void) handleRequestWithURL: (NSURL *) url bundleID: (NSString *) appBundleID

{

NSDictionary *params = [self.mss parseURL:url fromApp:appBundleID];

if ([self.mss isSSORequest:params]) {

NSLog(@"SSO request received in class with MSS object");

ssoURL = url;

ssoAppID = appBundleID;

ssoDelegate = [[AvitekSSODelegate alloc]init];

...

self.mss = [[OMMobileSecurityService alloc]initWithProperties:sdkProps delegate:ssoDelegate];

[self.mss setup];

}

Next, when the client app (AvitekScheduler) invokes setup, the SDK invokes the agent app and so here in the agent app we invoke processSSORequest:presenter: on the SDK to process the authentication request.

//process SSO request i.e start authentication process for SSO client

-(void) ssoProfileDownloaded

{

queryParams = [self.mss parseURL:ssoURL fromApp:ssoAppID];

[self.mss processSSORequest:queryParams presenter:self];

}

The SDK in the agent app starts the authentication process with OAM server on behalf of the client app and calls back the delegate's didFinishAuthentication:error: method when it's done.

AvitekSSODelegate.m:

- (void)didFinishAuthentication: (OMAuthenticationContext *)context error: (NSError *)error

{

NSLog(@"SSO finish authentication\nUser : %@\n Error : %@",

  context.userName,error.localizedDescription);

  self.ctx = context;

  self.err = error;

  NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

 [notificationCenter postNotificationName:@"SSO Finish Authentication" object:nil];

LoginViewController.m:

- (void)viewDidLoad

{

 [super viewDidLoad];

 // Do any additional setup after loading the view from its nib.

  ... 

NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];

[notificationCenter addObserver:self selector:@selector(ssoFinishAuth) name:@"SSO Finish Authentication" object:nil];

...

// dismiss the SDK screen; complete the SSO request and the response is sent to the SSO client

-(void) ssoFinishAuth

{

[self dismissViewControllerAnimated:true completion: nil];

[self.mss completeSSORequest:queryParams presenter:self error:ssoDelegate.err];

}

This delegate implementation above processes the request and via notification allows the SSO agent to invoke the completeSSORequest:presenter:error: on the SDK. The SDK checks whether the client app is registered and sends the response back to the calling client app.

Social Login

Relying Party authentication (i.e. the ability to enable your app to use Facebook, LinkedIn, Google etc as OAuth or OpenID providers thus allowing for social logins) is identical to invoking authentication services as outlined above. The configuration for this is done entirely on the server side. There really is only one caveat and that is that if the same app authenticates against different OAM servers or with the same OAM server but different authentication schemes, then one OMMobileSecurityService instance should be created for each server or authentication scheme. So, for example, in this case, since the same AvitekInventory app authenticates against OAM server and Facebook for different use cases, we create separate instances of OMMobileSecurityService to handle each use case.

Strong Authentication 

From an app perspective and the perspective of a mobile app developer, there are no additional development tasks that are required to enable your app  for KBA/OTP based strong authentication or collecting and sending mobile device context information for this purpose. The SDK automates all of this and this is enabled via server side configuration.

Comments:

Post a Comment:
Comments are closed for this entry.
About

Kanishk Mahajan is a Principal Product Manager in Oracle Identity Management with product responsibility within the Oracle Access Management suite

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today