Skip to main content

Native Mobile App Integration Guide

Introduction

Use this guide to enable the integration of and the appropriate redirection to iOS, Android, and Windows RT native mobile applications, post-authentication. Through this integration, 2-Factor Authentication and Single Sign-on (SSO) access can be achieved.

Workflow Diagram:

44831084.png

Prerequisites

1. Have native mobile application(s) and access to the source code

2. Create a New Realm for the native mobile app(s) integration in the SecureAuth IdP Web Admin

3. Configure the following tabs in the Web Admin before configuring the Post Authentication tab:

  • Overview – the description of the realm and SMTP connections must be defined

  • Data – an enterprise directory must be integrated with SecureAuth IdP

  • Workflow – the way in which users will access this application must be defined

  • Multi-Factor Methods – the Multi-Factor Authentication methods that will be used to access this page (if any) must be defined

Native Mobile App Configuration Steps

Define URL Scheme for Native Mobile Application

Android and iOS native mobile applications enable the registration of the app to a certain custom URL scheme

This step may have already been completed when the app was first developed; but if not, it is important that a unique URL scheme is created to ensure that it will not conflict with any other applications

For this configuration, the custom URL scheme foo will be used

Android

Add an intent filer to the activity in the AndroidManifest.xml file

<activity android:name=".LoginActivity" android:launchMode="singleTask">
  …
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="foo" />
    </intent-filter>
   …
</activity>

iOS

44831085.png

1. Open the Info.plist file, right-click to Add Row, and select URL types as the key

2. Right-click on the new URL types row to Add Row, and an Item will be created underneath it

3. Expand the new added item and set the URL Identifier to a unique value that uses a reverse domain style, e.g. com.myapp.foo

4. Add Row under the item, select URL Schemes as the key, and set it to foo

Windows RT

The application receives activation events only for the URI scheme names listed in the package manifest

Indicate whether the application handles the secureauthclient URL scheme name

This is a brief description of each of the fields that will be filled out:

Field

Description

Name

Choose a name for a group of file types that share the same display name, logo, info tip, and edit flags. Choose a group name that can stay the same across app updates.

Note: The Name must be in all lower case letters.

Display Name

Specify the display name to identify the URI scheme name in the Set Default Programs on the Control Panel.

Logo

Specify the logo that is used to identify the URI scheme name in the Set Default Programs on the Control Panel. If no Logo is specified, the small logo for the app is used.

1. Select the Declarations tab

2. Select Protocol from the dropdown list, and click Add

3. Set the Name to secureauthclient

4. Save the change to package.appxmanifest

Launch External System Browser and Navigate to SecureAuth IdP for Authentication

Here, the application's existing authentication step (e.g. username and password in a view) is being replaced with launching an external system browser

The Start URL should be defined in the code or in the application's configuration file

Android

Add a control to the layout xml file first, then add the onClickListener to it

Note

Replace the https://secureauth.company.com/SecureAuth1/ value with the actual Fully Qualified Domain Name (FQDN) of the SecureAuth IdP appliance, followed by the native mobile app-integrated realm (configured below)

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  …
  Button button = (Button) findViewById(R.id.login_button);
  button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
      Intent i = new Intent(Intent.ACTION_VIEW, "https://secureauth.company.com/SecureAuth1/");
      startActivity(i);
    }
  });
  …
}

iOS

Add a control to the xib or storyboard file, then associate it with an action

Note

Replace the https://secureauth.company.com/SecureAuth1/ value with the actual Fully Qualified Domain Name (FQDN) of the SecureAuth IdP appliance, followed by the native mobile app-integrated realm (configured below)

- (IBAction) startLogin: (id)sender
{
 NSURL *url = [NSURL URLWithString:@"https://secureauth.company.com/SecureAuth1/"];
  [[UIApplication sharedApplication] openURL:url];
}

Windows RT

Add a button control and then attach a click event to it

Replace the https://secureauth.company.com/SecureAuth1/ value with the actual Fully Qualified Domain Name (FQDN) of the SecureAuth IdP appliance, followed by the native mobile app-integrated realm (configured below)

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
   String realmUrl = @"https://secureauth.company.com/SecureAuth1/"; 
   Uri newUri = new Uri(realmUrl); Windows.System.Launcher.LaunchUriAsync(newUri); 
}

Accept SecureAuth IdP Token in Mobile Native App

Whether the token coming from SecureAuth IdP is encrypted or not, it still needs to be accepted through the same step

If it is a clear text UserID, it can be used immediately; if it is encrypted, the optional next step must be administered

Android

Read the value out of the Query String

@Override
protected void onNewIntent(Intent intent) {
  Uri data = intent.getData();
  if (data != null) {
    String accessToken = data.getQueryParameter("UserID");
    // Use the accessToken.
  }
}

iOS

Read the value out of the Query String

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
  for (NSString *param in [[url query] componentsSeparatedByString:@"&"])
  {
    NSArray *parts = [param componentsSeparatedByString:@"="];
    if ([parts count] == 2 &&
        [[parts objectAtIndex:0] isEqualToString:@"UserID"])
    {
      NSString *accessToken = [parts objectAtIndex:1];
      // Use the UserID Query String.
    }
  }
  return YES;
}

Windows RT

The onActivated event handler receives all activation events

The Kind property indicates the type of activation events, and this example is set up to handle Protocol activation events

protected override void OnActivated(IActivatedEventArgs args)
{
   if (args.Kind == ActivationKind.Protocol)
   {
      ProtocolActivatedEventArgs protocolArgs = args as ProtocolActivatedEventArgs;
      if (protocolArgs != null)
      {
         string[] query = protocolArgs.Uri.Query.Substring(1).Split(new[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
         string userid;
         if (query.Length == 2)
         {
            if (query[0] == "userid")
               userid = query[1];
         }
      }
   }
}

(OPTIONAL) Decrypt SecureAuth IdP Token

In the case that the SecureAuth IdP token is encrypted, instruct the mobile application to make a web service call to obtain the decrypted value

Android

Non-time Sensitive GetUserId (POC)

Call the GetUserId function that is non-time sensitive, e.g. for POC

Note

Replace the secureauth.company.com value with the actual Fully Qualified Domain Name (FQDN) of the SecureAuth IdP appliance (two instances)

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.*;
import android.os.*;
import android.widget.TextView;
public class ksoap2sample extends Activity {
  /** Called when the activity is first created. */
  private static final String SOAP_ACTION = "https://secureauth.company.com/SecureAuthWS/UserService.asmx";
  private static final String METHOD_NAME = "GetUserId";
  private static final String NAMESPACE = "http://secureauth.com";
  private static final String URL = " https://secureauth.company.com/SecureAuthWS/UserService.asmx"; TextView tv;
@Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    tv=(TextView)findViewById(R.id.text1);
    call();
  }
public void call()
  {
    try {
      SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
      request.addProperty("EncryptedUserString", accessToken);
      SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
      envelope.dotNet=true;
      envelope.setOutputSoapObject(request);
      HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
      androidHttpTransport.call(SOAP_ACTION, envelope);
      Object result = (Object)envelope.getResponse();
      tv.setText(result.toString());
    } catch (Exception e) {
      tv.setText(e.getMessage());
    }
  }
}
Time Sensitive GetUserIdWithTimeCheck (Production)

Call the GetUserIdWithTimeCheck function that is time sensitive, e.g. for Production

Note

Replace the secureauth.company.com value with the actual Fully Qualified Domain Name (FQDN) of the SecureAuth IdP appliance (two instances)

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.*;
import android.os.*;
import android.widget.TextView;
public class ksoap2sample extends Activity {

  /** Called when the activity is first created. */
  private static final String SOAP_ACTION = "https://secureauth.company.com/SecureAuthWS/UserService.asmx";
  private static final String METHOD_NAME = "GetUserIdWithTimeCheck";
  private static final String NAMESPACE = "http://secureauth.com";
  private static final String URL = " https://secureauth.company.com/SecureAuthWS/UserService.asmx"; TextView tv;
@Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    tv=(TextView)findViewById(R.id.text1);
    call();
  }
public void call()
  {
    try {
      SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
      request.addProperty("EncryptedUserString", accessToken);
      request.addProperty("ValiditySeconds", 5);
      SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
      envelope.dotNet=true;
      envelope.setOutputSoapObject(request);
      HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
      androidHttpTransport.call(SOAP_ACTION, envelope);
      Object result = (Object)envelope.getResponse();
      tv.setText(result.toString());
    } catch (Exception e) {
      tv.setText(e.getMessage());
    }
  }
}

iOS

Non-time Sensitive GetUserId (POC)

Call the GetUserId function that is non-time sensitive, e.g. for POC

Note

Contact SecureAuth Support to download the files XMLGetUserID.h and XMLGetUserID.m

1. #import the header file XMLGetUserID.h

2. Implement the delegate, which is the callback function for the XMLGetUserID class

@interface ViewController : UIViewController <UITextFieldDelegate, XMLGetUserIDDelegate>

3. Add a method to initialize the class and make the web service call

- (void)getDecryptedUserID:(NSString*)encUserID
{
    XMLGetUserID *xmlGetUserID = [[XMLGetUserID alloc] init];
    NSArray *arry = [NSArray arrayWithObjects:encUserID, nil];
    xmlGetUserID.delegate2 = self;
    [xmlGetUserID callGetUserID:arry];
    xmlGetUserID = nil;
}

4. Implement the delegate from XMLGetUserID class

- (void)delegateGetUserID:(XMLGetUserID *)xml withDic:(NSDictionary *)dic
{
     if (dic.count > 0)
    {
        // User login
        self.IsLoggedIn = YES;
        self.userName.text = [dic valueForKey:@"GetUserIDResult"];
         [self updateLabelState:self.IsLoggedIn];
    }
}
Time Sensitive GetUserIdWithTimeCheck (Production)

Call the GetUserIdWithTimeCheck function that is time sensitive, e.g. for Production

Note

Contact SecureAuth Support to download the files XMLGetUserID.h and XMLGetUserID.m

1. #import the header file XMLGetUserID.h

2. Implement the delegate, which is the callback function for the XMLGetUserID class

@interface ViewController : UIViewController <UITextFieldDelegate, XMLGetUserIDDelegate>

3. Add a method to initialize the class and make the web service call

- (void)getDecryptedUserID:(NSString*)encUserID
{
    XMLGetUserID *xmlGetUserID = [[XMLGetUserID alloc] init];
    NSArray *arry = [NSArray arrayWithObjects:encUserID, nil];
    xmlGetUserID.delegate2 = self;
    [xmlGetUserID callGetUserID:arry];
    xmlGetUserID = nil;
}

4. Implement the delegate from the XMLGetUserID class

- (void)delegateGetUserID:(XMLGetUserID *)xml withDic:(NSDictionary *)dic 
{
     if (dic.count > 0)
    {
        // User login
        self.IsLoggedIn = YES;
        self.userName.text = [dic valueForKey:@"GetUserIDResult"];
         [self updateLabelState:self.IsLoggedIn];
    }
}

(OPTIONAL / OUT OF SCOPE) Maintain Native Mobile App's Token for Internal SSO

Once the native mobile application has obtained the authenticated UserID and has successfully logged in the user, it is up the customer's design whether to cache the token locally on the app to enable SSO access for subsequent mobile app launches

As an alternative design, the application can launch the external system browser to SecureAuth IdP, and allow SecureAuth IdP to inspect the token

Note

There are pros and cons to each design

One offers transparent SSO for subsequent logins, while the other offer great user revocation control

Contact SecureAuth Support for more information and to determine which design would best suit the needs

SecureAuth IdP Configuration Steps

Post Authentication

44831076.png

1. In the Post Authentication section, select Mobile Native App Launch Page from the Authenticated User Redirect dropdown

2. An unalterable URL will be auto-populated in the Redirect To field, which will append to the domain name and realm number in the address bar (Authorized/MobileAuth.aspx)

User ID Mapping

44832709.png

3. Select Authenticated User ID from the User ID Mapping dropdown

If the user ID is mapped to a different SecureAuth IdP Profile Property (Data tab), select that value instead

Mobile Browser Token

44831080.png

4. Set a Name for the Mobile Browser Token

Native Mobile Apps

44831081.png

5. Select True from the Enable Multi App dropdown if this integration will include more than one native mobile application

Select False if this integration is for only one native mobile application

6. Select True from the Enable Multi App Group Check dropdown if integrating multiple native mobile applications and if SecureAuth IdP will check user group information to allow or deny access

Select False if no group restrictions are required

7. Select True from the Place Groups in QueryString dropdown if the user group information will be returned to the application in a query string

8. Select True from the Place Profile Attributes in QueryString dropdown if the user profile attributes will be returned to the application in a query string

9. Select True from the dropdowns of the Attributes that will be sent in the assertion

Attributes that set to False will not be sent in the assertion

Custom URL Schemes

Note

This section's configuration varies depending on the selection made in step 6

Warning

Click Save once the configurations have been completed and before leaving the Post Authentication page to avoid losing changes

Forms Auth / SSO Token

44833086.png

These are optional configurations