Best Practices from Oracle Development's A‑Team

Social Federation with OAM Mobile & Social in Native iOS Applications

Andre Correa Neto
Cloud Solutions Architect


I've already posted an article about Social Federation with Mobile & Social (M&S) for web applications protected by Oracle Access Manager (OAM), showing users being authenticated against social network providers, like Google and Linkedin.
My coworker Chris Johnson also blogged about using Mobile & Social in a native iOS application. In his post, user authentication happens against OAM identity store.

In this post, we have both worlds. We're going to explore how to implement user authentication against social network providers via OAM's M&S component in a native iOS application. I will show the necessary configuration in the social network provider, in M&S and how to setup the Xcode project for M&S SDK as well as the necessary coding.

However, before going any further, I'd like to explore why we'd want to use M&S in the first place and not simply just wire up our iOS application directly to the social network provider.

There's an interesting saying that you can solve virtually any communication problem between two parties by having something in between them. In our case, not having M&S in between the iOS application and the social network provider is not the end of the world, as you can totally rely on the provider's APIs. Having M&S in the middle, however, brings a good advantage in terms of deployment speed and helps shielding iOS developers from the requirements of dealing with the provider's API. If today your iOS applications use Google for authenticating users, tomorrow you can add Facebook, Linkedin or Twitter without changing a single line of code in your applications. Notice I said "add", i.e., your mobile applications can offer its users the possibility of authenticating against multiple identity providers without any code changes.

Another subtle aspect is that the client application can (if configured) end up with two access tokens: one OAuth Access Token issued by the IdP (Identity Provider) and one JSON Web Token (JWT) issued by OAM Mobile & Social. If your application needs to consume protected resources from both the social network provider and from Mobile & Social, this is a great benefit.

At a high-level, the use case scenario being explored here is depicted in the following diagram. Notice OAM M&S intermediating the interaction between the iOS App and the IdP. Once the iOS application starts, it contacts M&S to start the authentication process (step 1). M&S sends back a view displaying one or more authentication options to the application (step 2). The user picks up one provider option, signaling M&S to authenticate with that provider (step 3). M&S relays the authentication request to the provider (step 4), who sends its own login screen (followed by consent screen) back to the application (step 5). Once the end user provides her credentials and consent (step 5), the IdP returns an access token to OAM M&S (step 6), who, in turn, adds its own JWT before returning both to the iOS application (step 7).


[caption id="attachment_29153" align="aligncenter" width="592"]Authentication Process Authentication Process[/caption]

The following sections cover in detail the necessary configuration for implementing the use case scenario.


Main Article

Internet Identity Provider

In this post, the term Internet Identity Provider is interchangeably used as Social Network Provider or just Identity Provider.

For the purposes of this post, I am going to show the necessary configuration having Google as the Identity Provider using the OAuth2 protocol.

The steps for creating the necessary footprint in Google are the very same ones presented in my previous post about Social Federation. I repeat them here for your convenience.

1 - Create a Project

Go to Google Developer's Console (https://console.developers.google.com) and create a project. Give it any name you wish. Within your newly created project, there are only two links you care about: Credentials and Consent Screen, as shown below:

[caption id="attachment_28824" align="aligncenter" width="814"]Google Developers Console Dashboard Google Developers Console Dashboard[/caption]

2 - Create a Web Client Application

Within the project, create Client Credentials for a Web Application. From Google's perspective, the client is M&S, not the iOS application. Thus, it is a web application.

[caption id="attachment_28827" align="aligncenter" width="800"]Web Application Credentials Web Application Credentials[/caption]

You're going to use CLIENT ID (1) and CLIENT SECRET (2) when configuring Google Social Identity Provider in M&S.

Do notice the REDIRECT URIS (3). For M&S, it must be http://<OAM_SERVER_HOST>:<OAM_SERVER_PORT>/oic_rp/return.


3 - Configure a Consent Screen for the Application

The values entered in the Consent Screen have no bearings on any M&S configuration. In Google's case, there's one consent screen per project and it's always presented whenever there's an incoming request with your application-specific CLIENT ID.

[caption id="attachment_28829" align="aligncenter" width="1023"]Consent Screen Consent Screen[/caption]


1. PRODUCT NAME. The value is used by the consent screen at runtime, as shown below. You can enter any value and it doesn't need to match anything in M&S configuration.

2. PRODUCT LOGO is the little icon that gets displayed right next to the user's picture.


[caption id="attachment_28833" align="aligncenter" width="321"]Consent Screen at Runtime Consent Screen at Runtime[/caption]


Mobile & Social

The necessary configuration in M&S is all done using the two links marked below in OAM's main screen:


[caption id="attachment_28835" align="aligncenter" width="443"]OAM M&S OAM M&S[/caption]

1 - Create a custom Internet Identity Provider for Google

This is how we do it: Under the Social Identity link, create a new Internet Identity Provider for the oauth protocol using the values as seen (except for Name, Description, Consumer Key and Consumer Secret) in the following screen shot:



1. Arrows 1 and 2 refer to the CLIENT ID and CLIENT SECRET obtained in Google Developer's Console. Refer to step 2 of the previous section.

As for the user attributes to be returned by Google Internet Identity Provider, rolling down the screen, here's how they're defined:


[caption id="attachment_28946" align="aligncenter" width="576"]Google OpenID Connect (OAuth 2) Internet Identity Provider (cont'd) Google OAuth 2 Internet Identity Provider (cont'd)[/caption]

2 - Create an Application Profile for the iOS application in both Mobile Services and Social Identity.

The application profiles to be created are required to be given the same name under Mobile Services and Social Identity. In our sample, the name is ShowRoomiPhone.

The Mobile Services Application Profile deals with registration configuration for the mobile application as well as how M&S interacts with the application, whether via an embedded or external browser.


[caption id="attachment_28836" align="aligncenter" width="594"]Mobile Services Application Profile Mobile Services Application Profile[/caption]


In this first section of our Mobile Services Application Profile, the values are the default ones (except for Name and Description). Time allowing, I will come back on a future post talking about these settings. For the purposes of this post, we don't need to change any of them.


[caption id="attachment_28838" align="aligncenter" width="620"]Mobile Services Application Profile (cont'd) Mobile Services Application Profile (cont'd)[/caption]


In the second section of the screen it's important to call out two fields:

1. Internet Identity Services Webview: this defines how the screens of the Social Network Provider are "embedded" in your application. Embedded browser basically means a UIWebView for iOS-based applications.

2. Apple iOS Bundle ID: this is your iOS application identifier in M&S. It MUST match your iOS application Bundle Identifier.


[caption id="attachment_28839" align="aligncenter" width="745"]iOS Application Bundle Identifier iOS Application Bundle Identifier[/caption]


The Social Identity Application Profile defines everything else for the purposes of authentication and how M&S returns data to the mobile application, specifically:

a. Authentication types supported;

b. Whether and how user registration is necessary;

c. User Profile and Authentication service endpoints;

d. Application Profile Properties;

e. The Social Providers supported by the application and their attribute mappings;

We can see these in the following 2 screens:


[caption id="attachment_28842" align="aligncenter" width="555"]Social Identity Application Profile Social Identity Application Profile[/caption]



1. Mobile Application Return URL (app://show.room.iphone) MUST match a URL type in the iOS application (more on this shortly when I talk about the iOS application). The URL type is used by for registering the application into the iOS device so it can be invoked by other applications. It is used by M&S to return Internet Identity authentication data to the iOS application.

   TIP: Do NOT use http as the URL protocol (or URL Scheme), because that would instruct M&S to look for a real HTTP endpoint, which is not the case for a mobile application. Here I use "app" as the URL Scheme.

2. User Registration is not mandatory for mobile applications and can be disabled.

3. Make sure Authentication Service Endpoint is set to /internetidentityauthentication. This delegates authentication to the Social Identity providers defined at the bottom of the screen.

4. In Application Profile Properties, oic.app.idp.oauth.token = true makes M&S returning the IdP OAuth Access Token to the mobile application.

5. oic.app.user.token = true would make M&S returning a JWT to the mobile application. I've noticed this is actually not necessary. M&S will return its JWT anyways.


[caption id="attachment_28843" align="aligncenter" width="589"]Social Identity Application Profile (cont'd) Social Identity Application Profile (cont'd)[/caption]


The second part of the screen, as just shown, defines the available attributes to the application profile and their mappings with the Identity Providers. Together, these mean that only the mapped attributes are going to be available to the M&S Social Identity Application Profile.


Linkedin is also checked. This is ALL you need to do for allowing authentication against multiple Identity Providers. At runtime, M&S sends a view like the following to your iOS application:


[caption id="attachment_29154" align="aligncenter" width="318"]M&S Login Screen M&S Login Screen[/caption]


3 - Configure (or create a new one) the Mobile Service Domain and add the Mobile Service Application Profile to it.

A Service Domain defines the association between Mobile Service Application Profiles, their Service Profiles as well as (optionally) the protection levels for those services. The name of the service domain is typically used by client applications using the M&S SDK for initializing the APIs and later on interacting with M&S server. In my sample, I simply reuse the OOTB default MobileServiceDomain.


[caption id="attachment_28845" align="aligncenter" width="732"]Mobile Service Domain Application Profiles Mobile Service Domain Application Profiles[/caption]


1. Type MUST be Mobile Application;

2. Authentication Scheme MUST be Internet Identity Authentication;

3. ShowRoomiPhone Application Profile has been added;

4. On Service Profiles tab, make sure Authentication Service is set to InternetIdentityAuthentication, as in the following screen shot. This is essential when the iOS application tries to register itself in M&S at runtime.


[caption id="attachment_28852" align="aligncenter" width="668"]Mobile Service Domain Service Profile Mobile Service Domain Service Profile[/caption]


The iOS Application

The sample iOS application is really just a test application. All it does, for the time being, is writing the tokens it gets back from M&S to the output. In a future post, I will show how we can use these tokens for making secure calls to REST-based services.

1. Download M&S iOS SDK from this link and extract it to your local disk..

2. Add the SDK libraries to your Xcode project.

Drag the libIDMMobileSDK.a file, PublicHeaders and PublicResources folders and drop them right over your application project in Xcode. This will get your project automatically configured with M&S SDK.

[caption id="attachment_28856" align="aligncenter" width="669"]Adding M&S SDK libraries to Xcode project Adding M&S SDK libraries to Xcode project[/caption]


This is how your project should look like after adding those libraries:


[caption id="attachment_28858" align="aligncenter" width="230"]XCode Project with M&S SDK libraries XCode Project with M&S SDK libraries[/caption]


M&S SDK depends on CoreLocation, Security and SystemConfiguration frameworks. Make sure they're also included in your project.


[caption id="attachment_28963" align="aligncenter" width="218"]Required Frameworks Required Frameworks[/caption]


3. In your project Build Settings, add the following flags to Other Linker Flags in the Linking section: -ObjC -all-load. Explanations here.


[caption id="attachment_28939" align="aligncenter" width="730"]Linker Flags Linker Flags[/caption]


4. Add a URL type to your iOS application. This is done in the Info section of your application project in XCode. The URL type is composed of <URL Scheme>://<Identifier> and MUST match Mobile Application Return URL in M&S Social Identity Application Profile. In my example, <URL Scheme> value is app, and <Identifier> value is show.room.iphone.


[caption id="attachment_28883" align="aligncenter" width="831"]Application URL Type Application URL Type[/caption]

Again, this URL is used by M&S to callback the iOS application. At runtime, we can verify it by looking at this TCP stream sample captured with the Wireshark sniffer tool. Notice the URL Type in the response's Location header.


GET /oic_rp/return?state=3ec418cdec53976fb110b076faef4c7065a11792&code=4/VSYXo_7v7rslAf6rdS3T7kVBjLifNIWnCcvKgDGD-vI.gtM2tGFEacYUEnp6UAPFm0FsfCHMkgI HTTP/1.1
Host: slc05ylp.us.oracle.com:14101
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cookie: JSESSIONID=dncVJT4HGCGtqjF30GklycQHvmyRs6vHp5PLhRTvL8HLwzgZP8cp!575725555
Accept-Language: en-us
Origin: https://accounts.google.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D167

HTTP/1.1 302 Moved Temporarily
Connection: close
Date: Fri, 31 Oct 2014 11:54:54 GMT
Transfer-Encoding: chunked
Location: app://show.room.iphone?oicMobileAppRequestID=ShowRoomiPhone&payload=%7B%22UserProfile%22%3A%7B%22mail%22%3A%22andreluiz.correaneto%40gmail.com%22%2C%22lastname%22%3A%22Correa%22%2C%22firstname%22%3A%22Andre+Correa%22%7D%2C%22IdentityProvider%22%3A%22Google_OAuth2_Mobile%22%2C%22Protocol%22%3A%22OAuth%22%2C%22OICMobileAssertionToken%22%3A%22eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6Im9yYWtleSJ9.eyJleHAiOjE0MTQ3NjAwOTU2MDcsIm9yYWNsZS5vaWMudG9rZW4ucnAuaWRwX3VyaSI6Ikdvb2dsZV9PQXV0aDJfTW9iaWxlIiwib3JhY2xlLm9pYy50b2tlbi5ycC51c2VyX2lkX3VyaSI6Im1haWw6YW5kcmVsdWl6LmNvcnJlYW5ldG9AZ21haWwuY29tIiwiYXVkIjoib2FtX3NlcnZlcjEiLCJpc3MiOiJJbnRlcm5ldElkZW50aXR5QXV0aGVudGljYXRpb24iLCJwcm4iOiJtYWlsOmFuZHJlbHVpei5jb3JyZWFuZXRvQGdtYWlsLmNvbSIsImp0aSI6IjU1NTgxMDQ1LTc2ZTAtNDcwZS04N2VkLTMzY2EyMzQxZjFjOSIsIm9yYWNsZS5vaWMudG9rZW4udHlwZSI6IlVTRVJUT0tFTiIsImlhdCI6MTQxNDc1NjQ5NTYwNywib3JhY2xlLm9pYy50b2tlbi51c2VyX2RuIjoibWFpbDphbmRyZWx1aXouY29ycmVhbmV0b0BnbWFpbC5jb20gR29vZ2xlX09BdXRoMl9Nb2JpbGUifQ.g-MY_GI5TO1EirItAJ1TAiQIu31NI_rzwlLieJMnYXUA6uMBbMn1s5cz-PBKytO56uriUP7DRITA2YgFFnvaGJsUpKllR4Of0gX-z-Xxr_EsdTyGtsgfhQqU8bD61eyaEoWOyMtfEt1-XvcRTyX9FPq5DGi8gzCgyG460Zv6_BU%22%2C%22oauth_access_token%22%3A%22%7B%5C%22access_token%5C%22%3A%5C%22ya29.rwCyg8dspjdMXhiqCMn_BRDboAGh_h52erDf9M6gbZI7NupiHnAgo4a5PTmkz9JW_oYrR1SOdE8Q0A%5C%22%2C%5C%22expiry%5C%22%3A3600%2C%5C%22consumer%5C%22%3A%5C%22ShowRoomiPhone%5C%22%2C%5C%22provider%5C%22%3A%5C%22Google_OAuth2_Mobile%5C%22%7D%22%7D
Content-Type: text/html;charset=UTF-8
X-ORACLE-DMS-ECID: 6af0f0aa917fd32e:4ef3b382:1495d09e8d8:-8000-000000000000e62d
X-Powered-By: Servlet/2.5 JSP/2.1


5. Import IDMMobileSDK.h into the classes where you expect to perform authentication with the SDK APIs.

6. Code the authentication process

6.1. In your application delegate class, implement method application:openURL:sourceApplication:annotation. This is the method invoked when your iOS application receives a callback from M&S via its URL type. In the method, you MUST post a notification to IDM Mobile SDK, which reacts depending on the type of message it receives, invoking the various methods in the OMMobileServiceDelegate protocol.

// Called when application in invoked via some URL - (BOOL)application:(UIApplication *)application             openURL:(NSURL *)url   sourceApplication:(NSString *)sourceApplication          annotation:(id)annotation {     NSLog(@"handling callback after authentication...");     NSMutableDictionary *userInfo = [[NSMutableDictionary alloc]                                      initWithCapacity:1];     [userInfo setObject:url forKey:OM_RESPONSE_URL];     //Post the notification to IDM Mobile SDK     [[NSNotificationCenter defaultCenter]      postNotificationName:OM_PROCESS_URL_RESPONSE      object:self      userInfo:userInfo];     return TRUE; }

6.2. Initialize M&S properties. Since these properties are very static in nature, you could have them in your ViewController's viewDidLoad method, as in:

- (void)viewDidLoad {     [super viewDidLoad];     NSMutableDictionary *sdkProps = [[NSMutableDictionary alloc] init];     [sdkProps setObject:OM_PROP_AUTHSERVER_OAMMS forKey:OM_PROP_AUTHSERVER_TYPE];     [sdkProps setObject:@"http://slc05ylp.us.oracle.com:14101" forKey:OM_PROP_OAMMS_URL];     [sdkProps setObject:@"ShowRoomiPhone" forKey:OM_PROP_APPNAME];     [sdkProps setObject:@"MobileServiceDomain" forKey:OM_PROP_OAMMS_SERVICE_DOMAIN];     self.mss = [[OMMobileSecurityService alloc]                                     initWithProperties:sdkProps                                     delegate:self];     [self.mss setup]; }


1. The initialization property values:

a) Key OM_PROP_OAMMS_URL is the OAM M&S server URL:

b) Key OM_PROP_APPNAME is the Mobile Service Application Profile name;

c) Key OM_PROP_OAMMS_SERVICE_DOMAIN is the mobile service domain to which the Mobile Service Application Profile has been added.

2. in the call self.mss = [[OMMobileSecurityService alloc] initWithProperties:sdkProps delegate:self]
delegate:self means that your ViewController implements the OMMobileServiceDelegate protocol, i.e., the varios methods called by OMMobileSecurityService.


6.2. Implement didReceiveApplicationProfile:error method of OMMobileServiceDelegate protocol for starting the authentication process.

- (void)didReceiveApplicationProfile:(NSDictionary *)applicationProfile error:(NSError *)error {     NSError *err = nil;     if(error) {         NSString *msg = @"Error in receiving application profile";         UIAlertView *av = [[UIAlertView alloc]initWithTitle:nil                                                     message:msg                                                    delegate:nil                                           cancelButtonTitle:@"OK"                                           otherButtonTitles:nil];         [av show];         av = nil;     }     else {         OMAuthenticationRequest *authReq = [[OMAuthenticationRequest alloc] init];         NSLog(@"Starting Authentication Process...");         err = [self.mss startAuthenticationProcess:authReq presenterViewController:self];     } }

didReceiveApplicationProfile method is automatically invoked by OMMobileSecurityService once the application receives the Application Profile data from M&S. The method call starting the authentication process is

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


6.3. Implement didFinishAuthentication:error method of OMMobileServiceDelegate protocol for receiving the callback from OMMobileSecurityService after authentication. If authentication succeeds, you should have access to token returned by M&S and by the IdP (if configured in M&S Social Identity Application Profile, per oic.app.idp.oauth.token application profile parameter).


- (void)didFinishAuthentication: (OMAuthenticationContext *)context                           error: (NSError *)error {     NSLog(@"didFinishAuthentication\nUser : %@\n Token : %@\n Error : %@",           context.userName,context.tokenValue,error.localizedDescription);     if(error) {         NSString *msg = @"Error in authenticating user";         UIAlertView *av = [[UIAlertView alloc]initWithTitle:nil                                                     message:msg                                                    delegate:nil                                           cancelButtonTitle:@"OK"                                           otherButtonTitles:nil];         [av show];         av = nil;     }     else {         NSLog(@"Authentication success!");         context = [self.mss authenticationContext:false];         NSDictionary *tokens = [context accessTokens];         NSLog(@"%d",tokens.count);         for (id key in tokens) {             NSLog(@"%@: %@", key, [tokens objectForKey:key]);         }     } }


1. context.tokenValue returns the JWT returned by M&S;
2. [tokens objectForKey:OM_ACCESS_TOKEN] returns the OAuth access token returned by Google;


Ending Remarks

In this post I've showed how to configure OAM M&S to provide authentication against Internet Identity providers on behalf of a native iOS application. Specifically, I've taken Google as the remote Internet Identity provider with the OpenID Connect protocol. As of OAM M&S, there's no OOTB Internet Identity Provider for OpenID Connect (OAuth 2), so the article also covered how to create one.

The post also went into a considerable amount of detail on configuring Xcode and using M&S SDK in the iOS application.

The references I've consulted for this post are:

Managing Oracle Access Management Mobile and Social

Developing Mobile Services Applications with the iOS Client SDK

See you next time!

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha