10 Developing Mobile Services Applications with the Android Client SDK

This chapter describes how to develop Mobile Services applications with the Android Client SDK. This SDK serves as a security layer for developing secure mobile applications on Android devices. It essentially simplifies the development of the applications by taking control of authentication, authorization, user profile services and secure storage. The minimum Android version supported by the Mobile and Social Android Client SDK is Android 2.2. This chapter provides the following sections:

10.1 Getting Started With the Android Client SDK

This SDK (oamms_sdk_for_android.zip) is included in the Oracle Access Management distribution package and can also be downloaded from the Oracle Technical Network (OTN) website.

In addition to this Developer's Guide, API documentation in HTML format is provided in the SDK. Refer to the API documentation for descriptions of API classes, interfaces, constructors, methods, and fields.

The Mobile Android Client SDK is provided as a library project. It contains five modules:

  • Authentication Module - Processes authentication requests on behalf of users, devices, and applications.

  • User Role Module - Provides User Profile Services that allow users and applications to get User and Group details from a configured Identity store.

  • REST Handler Module - Provides access to REST web services and automatic injection of tokens for Access Manager protected REST web services.

  • Cryptography Module - Provides simplified APIs to perform cryptography tasks like hashing, encryption, and decryption.

  • Secure Storage Module - Provides APIs to store and retrieve sensitive data using the preferences storage of Android.

Important:

The minimum Android version supported by the Mobile and Social Android Client SDK is Android 2.2.

10.1.1 Developing and Packaging Android Applications

Review the following notes prior to developing and packaging Android applications.

Import the Library Project Into Your Workspace

The oamms_sdk_for_android.zip archive contains an IDMMobileSDK folder. The IDMMobileSDK folder is a library project.

To import the library project into your workspace in Eclipse, choose File > Import > Existing projects into workspace.

Point Your Application to the Library

In Eclipse, choose Project > Properties > Android > Library and add a reference to the library project.

Add Permission Statements Before Compiling

Before compiling your application, add the following <uses-permission> statements to the application consuming Mobile and Social services. Add the statements to the AndroidManifest.xml file. Your application must include these statements, otherwise it will crash.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

For more information about requesting permissions, see the Android Developer documentation:

http://developer.android.com/index.html

10.2 Invoking Authentication Services With the Android Client SDK

This section provides sample code that demonstrates how to authenticate with the Mobile and Social server. Refer to "Configuring Mobile Services" in Oracle Fusion Middleware Administrator's Guide for Oracle Access Management for information about configuring the Mobile and Social server.

Step 1: Create an Object of OMMobileSecurityService

Create an object of OMMobileSecurityService as follows by providing the required Mobile and Social server details.

OMMobileSecurityService mss = new OMMobileSecurityService(context, configProperties, callback);

Table 10-1 OMMobileSecurityService Parameters

Parameter Description

context

The context of the Application object. Pass the context that is returned by Context#getApplicationContext().

See the following URL for more information about the getApplicationContext() method:

http://developer.android.com/reference/android/content/Context.html#getApplicationContext()

Do not pass an Activity reference because the OMMobileSecurityService instance exists throughout the application life cycle and if the OMMobileSecurityService instance has a reference to an Activity, it could lead to a memory leak.

configProperties

The Map that contains the configuration properties. See Table 10-5 in Section 10.4, "Initialization Properties" for the list of configuration properties.

callback

Specifies an instance of a class that has implemented the interface OMMobileServiceCallback. The SDK uses this to return control to the application after calling OMMobileSecurityService#setup(), OMMobileSecurityService#authenticate(), and OMMobileSecurityService#logout().


Initialization Sample Code

        Map<String, Object> configProp = new HashMap<String, Object>();
 
          //The following strings should be available in configProperties. 
          //Otherwise, IllegalArgumentException will be thrown
          configProp.put(OMMobileSecurityService.OM_PROP_AUTHSERVER_TYPE, OMMobileSecurityService.AuthServerType.OAMMS);
          configProp.put(OMMobileSecurityService.OM_PROP_OAMMS_SERVICE_DOMAIN, "MobileServiceDomain");
          configProp.put(OMMobileSecurityService.OM_PROP_APPNAME,  "MyApp");
          configProp.put(OMMobileSecurityService.OM_PROP_OAMMS_URL, "http://www.example.com:14100");
 
        OMMobileSecurityService mss = new         OMMobileSecurityService(getApplicationContext(), configProp, callback);
        //getApplicationContext():  context of the calling application; 
        //callback: Instance of a  class which has implemented the interface 
        //OMMobileServiceCallback
  • OM_PROP_OAMMS_URL - The URL (<protocol>://<host>:<port>) required to reach the Mobile and Social server. Only the HTTP and HTTPS protocols are supported.

  • OM_PROP_OAMMS_SERVICE_DOMAIN - Specifies the name of the service domain that has been created on the Mobile and Social server. The application profile that OM_PROP_APPNAME refers to should be defined as an application profile in this service domain. For more information, see "Defining Service Domains" in the Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.

  • OM_PROP_APPNAME - A unique identifier that identifies the application. This String value must match the application "Name" value located in the Application Profile section of the Mobile and Social server administration console. For more information, see "Defining Application Profiles" in the Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.

Note:

If your apps will authenticate against a single OAM server or a single ServiceDomain, there should be only one instance of the OMMobileSecurityService object throughout the application life cycle. This is required to maintain one valid session with the server at a time, and also to support the single sign-on feature.

To maintain one instance of OMMobileSecurityService throughout the application life cycle, either extend the Application class in the Android SDK, or create a custom static singleton class.

Refer to the Android documentation for information about extending the Application class:

http://developer.android.com/reference/android/app/Application.html

If your apps will authenticate against different OAM servers, or with the same OAM server but different authentication schemes, then one OMMobileSecurityService instance should be created for every server or authentication scheme. For example, if the same app authenticates against OAM server and against Facebook for different use cases, then create separate instances of OMMobileSecurityService to handle both use cases. On the OAM server, configure one ServiceDomain with a "Mobile Service Authentication" authentication scheme, and configure the other with a "Social Identity Authentication" authentication scheme.

Step 2: Register the Activity

Register the current activity before invoking methods in OMMobileSecurityService, such as setup(), authenticate(), and processSSORequest(Intent intent). Deregister the activity when it is not in the foreground. Do this to ensure that there is not a memory leak. To give the reference to the current activity, register the current activity in onResume() and deregister the activity in onPause() for all activities that call the methods mentioned above. If any of these methods are called in onCreate() of the activity, then before calling these methods, register the activity using OMMobileSecurityService#registerActivity(activity). When the activity moves to the background, deregister the activity using the method OMMobileSecurityService#deregisterActivity()).

mss.registerActivity(this);

Step 3: Call the setup() Method

Call the setup() method, which initiates the download of your application profile from the Mobile and Social server.

mss.setup();

This is an asynchronous call. When the application profile download completes, or if a problem like network unavailability is encountered, the SDK returns control to the calling activity by using the following callback:

OMMobileServiceCallback#processSetupResponse(OMOMMobileSecurityService mss, OMApplicationProfile profile, OMMobileSecurityException mse)

If the application profile could not be downloaded, the exception details can be found in OMMobileSecurityException mse. The SDK downloads and stores the application profile. The SDK will not download the application profile on subsequent calls to OMMobileSecurityService#setup() until the ProfileCacheDuration setting has expired. The ProfileCacheDuration setting is defined in the application profile.

Step 4: Call the authenticate() Method

Once the setup successfully completes, the business application can perform authentication by calling OMMobileSecurityService#authenticate(). This is an asynchronous call and the SDK will return control to the application once authentication is completed or if authentication has failed for some reason. The control will be returned to the application through OMMobileServiceCallback#processAuthenticationResponse(OMMobileSecurityService mss, OMAuthenticationContext context, OMMobileSecurityException mse). All the details with respect to the authenticated session are available in the OMAuthenticationContext context. If authentication fails for some reason, the details are available in OMMobileSecurityException mse.

Set up the page as follows:

View view = mss.authenticate();

setContentView(view);

The authenticate() method will return a ViewFlipper object that holds the processing view. When the view is focused it will trigger the actual authentication flow.

If a valid authentication context is already available in the cache for the above request, then it will return control back to the calling business application without performing any request to the server.

The following sample code demonstrates the processAuthenticationResponse() method:

public void processAuthenticationResponse(OMMobileSecurityService mss, OMAuthenticationContext context, OMMobileSecurityException mse)
 
{
    if (context != null)
    {       
        Toast.makeText(getApplicationContext(), "Logged in successfully.", Toast.LENGTH_LONG).show();
    }
    else
    {
        Toast.makeText(getApplicationContext(), "Failure in login due to " + mse.getLocalizedMessage(), Toast.LENGTH_LONG).show();
    }
}

Note:

To customize the login view or the knowledge-based authentication (KBA) view, see "Login View and KBA View Customization" later in this chapter.

Step 5: Call the logout() Method

Call the following method to logout the user:

mobileSecurityService.logout(boolen isForgetDevice)

Table 10-2 logout() Method Parameter

Parameter Name Parameter Values Type

isForgetDevice

true - Clears everything stored in the credential store, including hashed passwords for supporting offline authentication, client registration handles, and tokens.

false - Clears only user session-related items from the store, such as tokens.

Boolean


The Mobile and Social server logout operation involves invoking a REST Web service to delete tokens maintained on the server. Consequently, the callback OMMobileServiceCallback#processLogoutResponse(OMMobileSecurityService mss, OMMobileSecurityException mse) is called after the server interaction is completed. Below is a sample callback implementation:

public void processLogoutResponse(OMMobileSecurityService mss, OMMobileSecurityException mse)
{
            if(mse == null)
            {
                Toast.makeText(getApplicationContext(), "Logout is successful!", Toast.LENGTH_SHORT).show();
            }
            else
            {
                Toast.makeText(getApplicationContext(), "Logout failure. " + mse.getErrorMessage(), Toast.LENGTH_SHORT).show();
            }
} 

10.3 URL-Based Initialization

To initialize the SDK using a URL, use a URL that contains the required configuration properties. The URL should be of the following format:

<scheme>://[host]?<parameter1>::=<value1>&<parameter2>::=<value2>&...&<parameterN>::=<valueN>

where:

Following is a sample URL for initializing an app with Mobile and Social server details:

samplescheme://settings?AuthServerType::=OAMMSAuthentication&
ApplicationName::=SampleApp&
OAMMSURL::=http://www.example.com:14100&
OAMMSServiceDomain::=MobileServiceDomain

This URL can be sent to users by e-mail or another means and, once the user clicks the URL using their Android mobile device, the corresponding app is invoked. The intent, which contains the configuration URL, has to be passed to the following method. The method, in turn, parses the URL and extracts the SDK configuration properties:

Set<String> filters = new HashSet<String>();
filters.add(OM_PROP_AUTHSERVER_TYPE);
filters.add(OM_PROP_APPNAME);
filters.add(OM_PROP_OAMMS_URL);
filters.add(OM_PROP_OAMMS_SERVICE_DOMAIN);
OMMobileSecurityService.parseConfigurationURI(context, intent, persistInSharedPreferences,keyInSharedPreference, filters)

Table 10-3 parseConfigurationURI() Method Parameters

Parameter Name Description

context

The context of the calling application. Always passContext#getApplicationContext().

intent

The intent that contains the SDK configuration properties.

persistInSharedPreferences

Indicates if the SDK configuration properties have to be persisted in SharedPreferences. This has to be mentioned as true so that the constructor OMMobileSecurityService(Context context, String configurationPropertiesKey, OMMobileServiceCallback callback) can create an instance of OMMobileSecurityService based on the configuration properties stored in SharedPreferences.

keyInSharedPreference

The key against which the SDK configuration properties have to be stored.

filters

Set of property strings in the configuration URL to be returned in the Map of configuration properties and optionally persisted in SharedPreferences. The remaining parameters in the URL extracted from the configuration URL are ignored by the IDM Mobile SDK.


Once the configuration properties are stored in SharedPreferences by calling the parseConfigurationURI() method, an instance of OMMobileSecurityService can be created as follows:

OMMobileSecurityService mobileSecurityService = OMMobileSecurityService(Context context, String configurationPropertiesKey, OMMobileServiceCallback callback);

Table 10-4 OMMobileSecurityService Parameters for URL-Based Initialization

Parameter Description

context

The context returned by Context#getApplicationContext()

configurationPropertiesKey

The key against which the SDK configuration properties have been stored. This should be the same as the key that was mentioned as keyInSharedPreference in OMMobileSecurityService.parseConfigurationURI(context, intent, persistInSharedPreferences,keyInSharedPreference).

callback

An instance of a class that has implemented the interface OMMobileServiceCallback. This is used by the SDK to return control to the application after calling OMMobileSecurityService#setup() and OMMobileSecurityService#authenticate()


10.4 Initialization Properties

Use the following initialization properties to initialize the SDK. The property names starting with OM_PROP are a part of the OMMobileSecurityService class. Use these properties to specify the entries being passed in the Map to the constructor: OMMobileSecurityService(context, configProperties, callback). For URL-based initialization, the name of the parameters and their corresponding values are included in parentheses.

Table 10-5 Android Client SDK Initialization Properties

Property Name Property Value(s) Type

OM_PROP_AUTHSERVER_TYPE

(AuthServerType)

  • OMMobileSecurityService.AuthServerType.OAMMS

    (OAMMSAuthentication)

  • OMMobileSecurityService.AuthServerType.HTTPBasicAuth

    (HTTPBasicAuthentication)

Enum (OMMobileSecurityService.AuthServerType)

OM_PROP_OAMMS_URL

(OAMMSURL)

Required property. A String that contains the protocol, host, and port required to reach the Mobile and Social server. Only the HTTP and HTTPS protocols are supported.

<protocol>://<host>:<port>

String

OM_PROP_OAMMS_SERVICE_DOMAIN

(OAMMSServiceDomain)

Required property. Specifies the name of the service domain that has been created on the Mobile and Social server. The application profile that OM_PROP_APPNAME refers to should be defined as an application profile in this service domain. For more information, see "Defining Service Domains" in the Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.

String

OM_PROP_APPNAME

(ApplicationName)

Required property. A unique identifier that identifies the application. This String value must match the application "Name" value located in the Application Profile section of the Mobile and Social server administration console. For more information, see "Defining Application Profiles" in the Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.

String

OM_PROP_MAX_LOGIN_ATTEMPTS

(MaxLoginAttempts)

The maximum number of login attempts allowed by the user. Optional. If this property is not specified, the default is 3.

Integer

OM_PROP_AUTH_KEY

(AuthKey)

The key that must be used to store the OMCredential object in shared preferences.

This is an optional property. If it is not specified, it is stored using the <login_url>_<applicationName>_<serviceDomain> key if all the values are not null. Otherwise, it is stored using <applicationName> alone.

String

OM_PROP_LOCATION_UPDATE_ENABLED

(LocationUpdateEnabled)

Use this property to enable or disable location updates. If it is enabled, then the SDK will collect location details of the device and send it to the server.

Boolean

OM_PROP_AUTO_LOGIN_ALLOWED

(AutoLoginAllowed)

Optional. Specifies if auto-login is enabled. Either true or false. By default it is disabled.

Boolean

OM_PROP_REMEMBER_USERNAME_ALLOWED

(Remember User name Allowed)

Specifies if the Remember User Name feature is enabled. Either true or false. By default it is disabled.

Boolean

OM_PROP_REMEMBER_CREDENTIALS_ALLOWED

(RememberCredentialsAllowed)

Specifies if the Remember Credentials feature is enabled. Either true or false. By default it is disabled.

Boolean

OM_AUTO_LOGIN_DEFAULT

(AutoLoginDefault)

Represents the default preference for the auto-login option box. Either true or false. Default value is false.

Boolean

OM_REMEMBER_USERNAME_DEFAULT

(RememberUsernameDefault)

Represents the default preference for the Remember User Name option box. Either true or false. The default value is false.

Boolean

OM_REMEMBER_CREDENTIALS_DEFAULT

(RememberCredentialDefault)

Represents the default preference for the remember credentials option box. Either true or false. Default value is false.

Boolean


The following OM_PROP_CRYPTO_SCHEME cryptography property is an optional property. If the application requires offline authentication and this property is not specified, the default crypto scheme is SSHA512. This is used to hash / encrypt the password and store it for offline authentication later, if required by the application.

This property can also be set using the Mobile and Social server console. Choose Custom Settings > Mobile Custom Attributes and use the Attribute Name and Attribute Value listed in the last two columns in the table.

For information about the cryptography module included in the Mobile and Social Android Client SDK, see Section 10.12, "Using the Cryptography APIs."

Table 10-6 Cryptography Scheme Property Attributes for the Android Client SDK

Property Name Property enum Values Attribute Name Attribute Value

OM_PROP_CRYPTO_SCHEME

(CryptoScheme)

PLAINTEXT("PlainText")

Enum(CryptoScheme)

PlainText

AES("AES")

AES

SHA1("SHA-1")

SHA-1

SHA224("SHA-224")

SHA-224

SHA256("SHA-256")

SHA-256

SHA384("SHA-384")

SHA-384

SHA512("SHA-512")

SHA-512

SSHA1("SaltedSHA-1")

SaltedSHA-1

SSHA224("SaltedSHA-224")

SaltedSHA-224

SSHA256("SaltedSHA-256")

SaltedSHA-256

SSHA384("SaltedSHA-384")

SaltedSHA-384

SSHA512("SaltedSHA-512")

SaltedSHA-512


10.5 About Offline Authentication

Mobile and Social supports offline authentication. Use the enum OMConnectivityMode to specify how offline authentication should happen.

  • OMConnectivityMode.ONLINE - Always authenticate with the server. Fails if device cannot reach the Internet.

  • OMConnectivityMode.OFFLINE - Authenticates locally with cached credentials. Offline authentication happens even if the device is online and can reach the server.

  • OMConnectivityMode.AUTO - Authentication happens with the server if the server is reachable and happens offline if the device is not connected to the Internet.

An example is shown here:

OMAuthenticationRequest authRequest = new OMAuthenticationRequest();
authRequest.setConnectivityMode(OMConnectivityMode.ONLINE);
View authView = authenticate(authRequest);

Because offline authentication is part of OMAuthenticationRequest, the setting is valid for the current request alone. During offline authentication if the number of failure attempts exceeds the value of the OM_PROP_MAX_LOGIN_ATTEMPTS property (discussed in the "Initialization Properties" section), the locally stored credentials are deleted and online authentication is attempted.

Note:

Offline authentication only works if the "Offline Authentication" setting in the server is set to "Allowed." See "Editing or Deleting an Application Profile" in the Administrator's Guide for Oracle Access Management for more information.

To support offline authentication, the SDK captures and stores the user credentials. The password of the user will either be hashed or encrypted based on the value set for the property OM_PROP_CRYPTO_SCHEME. If the application requires offline authentication and this property is not specified, the default crypto scheme is SSHA512.

10.6 Invoking Social Identity Authentication Using the Android Client SDK

This section provides sample code that shows how to do Social Identity Authentication (also called Relying Party Authentication) with the Mobile and Social Server. Refer to the "Configuring Social Identity" chapter in the Administrator's Guide for Oracle Access Management for information about configuring the Mobile and Social server.

To authenticate using a Relying Party, the data scheme in the main activity of the application should match the URL scheme configured in the Application profile. See the following page for details.

http://developer.android.com/guide/topics/manifest/data-element.html

Call OMMobileSecurityService#authenticate() as usual to authenticate. The SDK will retrieve the necessary settings from the server and authenticate with the Relying Party. Once authenticated, retrieve the authentication context from the mobile security service instance (OMMobileSecurityService#retrieveAuthenticationContext()). The retrieved authentication context object also contains Identity Provider specific information. The authentication context allows you to get the logged in user name, the identity provider name, and the access token of the identity provider. Please refer to the SDK documentation for more details.

Note:

Include the following code snippet in the main activity of an app that authenticates against Social Identity Providers like Facebook, Google, and so on. The main activity is the activity that is defined as the Android Package in the Application Profile settings on the Mobile and Social Server.

The Android Package field should be set to the fully qualified name of the activity in the Android application. The activity should have <data android:scheme="xyz" /> in its <intent-filter> and xyz should be the same as the URL scheme.

@Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState); 
        ...
        Intent intent = getIntent();
        if (intent.getExtras()!= null) 
        {
            try
            {
                mMobileSecurityService.processSSORequest(intent);
            } 
            catch (OMMobileSecurityException e)
            { 
                Log.w(TAG, e.getLocalizedMessage());
            }
        }
        ...
    }

10.7 Invoking the Mobile Single Sign-on Agent App

This section describes how to use the Android Client SDK to interact with a mobile single sign-on agent app. For conceptual information about mobile single sign-on in Mobile and Social, see the "Understanding Mobile Single Sign-on (SSO) Capabilities" and "Understanding Mobile and Social" in Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.

The Sample Mobile SSO Agent App

Mobile and Social provides a sample SSO agent app that illustrates the required logic. You can adapt this logic to any business app and enable the app to function as a mobile SSO agent. The sample Mobile SSO Agent App can be downloaded from the Oracle Technical Network (OTN) website.

Note that the data scheme of the sample Mobile SSO Agent App is "osa". Enter this as the URL Scheme in the Application Profile on the Mobile and Social Server. Essentially, the URL Scheme of the iOS SSO Agent App and the data scheme of Android SSO Agent App should be the same. Finally, when adding the Application Profile to a Service Domain on the Mobile and Social server, configure the Mobile Single Sign-on (SSO) Configuration attributes (Participate in Single Sign-on and Agent Priority).

For more information about configuring SSO on the Mobile and Social server, see "Editing or Deleting the Service Domain" and "Editing or Deleting an Application Profile" in the Administrator's Guide for Oracle Access Management.

For single sign-on to work, enter the Android Application signature of both the SSO Agent app and the SSO Client app in the respective application profiles. The application signature can be obtained programmatically using the following snippet of code that you place inside an activity in your app.

        try
        {
            packageInfo = getPackageManager().getPackageInfo(getApplicationContext().getPackageName(), PackageManager.GET_SIGNATURES);
 
            for (Signature signature : packageInfo.signatures)
            {
                Log.i(TAG, "The signature is : " + signature.toCharsString());
            }
        }
        catch (NameNotFoundException e)
        {
            e.printStackTrace();
        }

If you want to create your own Mobile SSO Agent App, refer to Section 10.10, "Creating a Custom Mobile Single Sign-on Agent App Using the Android Client SDK."

10.7.1 Invoking the Mobile Single Sign-on Agent app from another application(SSO Client)

When applications that are configured as SSO clients make a call to OMMobileSecurityService#authenticate() , the Android Client SDK delegates the request to the SSO Agent application if it is already installed on the device. Otherwise it throws an exception. The Android Client SDK frames the authentication request and invokes the SSO Agent app using an intent.

Note:

If an application (SSO client) needs to authenticate using the SSO Agent App, the main activity has to call OMMobileSecurityService#processSSORequest(intent). This is required because after the SSO Agent app authenticates, it sends details to the main activity of the SSO Client App using some intent. The SDK will appropriately populate its data structures in the SSO Client App with the details present in the intent.

The main activity is the activity configured on the Mobile and Social server as the "Android Package" in the Application Profile.

Refer to the following sample code:

          @Override
          public void onCreate(Bundle savedInstanceState)
          {
              super.onCreate(savedInstanceState);
              …
              …
              Intent intent = getIntent();
              if (intent.getExtras()!= null)
              {
                  try
                  {
                      mMobileSecurityService.processSSORequest(intent);
                  }
                  catch (OMMobileSecurityException e)
                  {
                      Log.w(TAG, e.getLocalizedMessage());
                  }
              }
              …
              …
          }

10.7.2 Invoking the Mobile Single Sign-on Agent App Using a Mobile Browser

Web apps can also use the single sign-on authentication features provided by the mobile SSO agent. This functionality requires Access Manager.

  1. Log on to the Oracle Access Management Administration Console.

    The Launch Pad opens.

  2. Under Access Manager click Authentication Schemes, then click the Create Authentication Scheme button.

    The "Create Authentication Scheme" tab opens.

  3. Create a new Authentication Scheme by completing the form as follows:

    • Name: MobileSSOScheme

    • Authentication Level: 2

    • Challenge Method: FORM

    • Challenge Redirect URL: /oam/server/

    • Authentication Module: LDAP

    • Challenge URL: /mobilesso?serviceDomain=MobileServiceDomain

      where MobileServiceDomain is the name of the domain that is configured for single sign-on.

    • Context Type: customWar

    • Context Value: /oic_rest

  4. In the Oracle Access Management Administration Console, do the following:

    1. Create a new Authentication Scheme in an Application Domain:

      Authentication Scheme: MobileSSOScheme

      (MobileSSOScheme is the scheme that was created in step one.)

    2. Create an HTTP Resource, for example /protectedRes, and protect the resource using the created Authentication Scheme (MobileSSOScheme). This is the URL that will be accessed from the mobile web browser and protected by a WebGate.

When the protected resource is accessed using a mobile browser, the server will invoke the Mobile SSO Agent App. Because the agent app makes a call to OMMobileSecurityService#processSSORequest(intent) in the onResume() of the main activity, the agent app will delegate the control to the SDK to handle complexities like authenticating, obtaining the OAM_ID token, injecting it, and returning control back to the browser. The browser will now be able to access the protected resource as the required token has been set by the SSO Agent App.

10.8 Invoking User Profile Services With the Android Client SDK User Role Module

This section describes how to use the Android Client SDK to create, read, update, or delete users and groups in a directory server that has been configured to work with Mobile and Social. To configure the Mobile and Social server to work with a directory server, see "Defining, Modifying, or Deleting a User Profile Service Provider" and "Defining, Modifying, and Deleting a User Profile Service Profile" in the Oracle Fusion Middleware Administrator's Guide for Oracle Access Management.

You can configure the User Role module to be used anonymously or only after authentication by adjusting the settings on the Service Protection tab in the Service Domain.

In both cases, you first need to obtain a reference to an instance of OMUserProfileService from the OMMobileSecurityService instance: OMMobileSecurityService#getUserRoleProfileService(OMAuthenticationContext).

The second step is to obtain either an instance of UserManager or RoleManager, depending on the operations to be performed. An instance of UserManager can be used to get User Details, whereas an instance of RoleManager can be used to get Group details from the Identity Store associated with your application's domain on the Mobile and Social server.

  1. Obtain an instance of OMUserProfileService by passing in the AuthenticationContext obtained after successful authentication. You can obtain the authentication context after authentication using OMMobileSecurityService#retrieveAuthenticationContext().

    In the following sample, mMobileSecurityService is an instance of OMMobileSecurityService.

    OMUserRoleProfileService userProfileService = mMobileSecurityService.getUserRoleProfileService(authContext); 
    

    If anonymous access to these services is needed, pass null.

    OMUserRoleProfileService userProfileService = mMobileSecurityService.getUserRoleProfileService(null);
    
  2. Obtain either an instance of UserManager or RoleManger as shown.

    OMUserManager userManager = userProfileService.getUserManager();
     
    OMRoleManager roleManager = userProfileService.getRoleManager();
     
    
  3. The following methods can be invoked using userManager. All these methods interact with the Mobile and Social server over a network, so these methods should be called from a background thread rather than a UI thread.

    public List<OMUser> searchUsers(Map<String, String> searchFilter, List<String> attrsToFetch, int startIndex, int size, boolean isSimpleSearch) throws OMMobileSecurityException
     
    public OMUser searchUser(String userId, List<String> attrsToFetch, boolean shouldPrefetchManager) throws IOException, JSONException, OMMobileSecurityException
     
    public OMUser modifyUser(String uid, String telephoneNumber, String mobile, String mail, String address) throws OMMobileSecurityException
     
    public boolean deleteUser(String userId) throws OMMobileSecurityException
     
     
    public boolean createUser(Map<String, String> attrVals) throws OMMobileSecurityException 
    

    The following methods can be invoked using roleManager. As is the case with methods in OMUserManager, all the methods in OMRoleManager should also be called from a background thread.

    public OMRole getRole(String roleName) throws IOException, JSONException,OMMobileSecurityException
     
    public boolean createRole(Map<String, String> attrVals) throws OMMobileSecurityException
     
    public OMRole modifyRole(String rolename, Map<String, String> attrVals) throws OMMobileSecurityException
     
    public boolean deleteRole(String roleName) throws OMMobileSecurityException
     
    public OMUser getUserFromRole(String userId, String role) throws OMMobileSecurityException
     
    public void addUserToRole(String roleName, Map<String, String> attrVals) throws OMMobileSecurityException
     
    public boolean deleteUserFromRole(String roleName, String userId) throws OMMobileSecurityException 
    

10.9 Invoking REST Web Services

You can use the Mobile and Social SDK to authenticate against Access Manager using the Mobile and Social service. After authenticating against Access Manager, the SDK gets a token and persists it in the cookie store and in local storage.

The Mobile and Social Android Client SDK provides the following method to access REST Web services or any Web resource protected by Access Manager:

OMMobileSecurityService#processHttpRequest(HttpRequest httpRequest)

To access them, however, the user should first authenticate. The Android Client SDK gets access tokens for any given resource using the user token obtained during authentication, provided the resource is protected by an Access Management 11g R2 WebGate.

In the following sample code, if a valid user token is not found for the current application (for example, if the user is not authenticated), the code throws an exception. Because this method contacts the server across the network, execute it in a background thread.

        HttpRequest httpRequest = new HttpGet("http://abc.example.com:7778/index.html");
        // It is important to set the User-Agent to the values configured in the OAM 11g R2
        // WebGate user defined parameters.
        // We need to configure OAM 11g R2 WebGate with these parameters:        //  i) OAMAuthUserAgentPrefix=<Prefix for User-Agent HTTP header> (Example: OIC)        // ii) OAMAuthAuthenticationServiceLocation=<OIC Server URL> (Example:
        //     http://host123.us.example.com:14100/oic_rest/rest/mobileoamauthentication)
        httpRequest.setHeader("User-Agent", "OAMMS-Agent");
        try
        {
            HttpResponse response = mss.processHttpRequest(httpRequest);
            // The developer may extract the useful information from the "response" object
        }
        catch (OMMobileSecurityException mse)
        {
            Log.d("processHttpRequest", mse.getLocalizedMessage());
        }

The OMMobileSecurityService#processHttpRequest(HttpRequest) method can obtain the required token from Access Manager only if the REST Web service is protected using an Oracle Access Management 11g R2 WebGate. The user defined parameter of the Access Management 11g R2 WebGate must contain the OAMAuthUserAgentPrefix and OAMAuthAuthenticationServiceLocation properties. The same property values must be specified by the mobile application in its header as shown in the sample code.

The following steps describe the internal flow when this method is called:

  1. OMMobileSecurityService#processHttpRequest(HttpRequest) invokes the URL provided by the mobile application.

  2. The Oracle Access Management 11g R2 WebGate returns a 401 error with the following details:

       HTTP/1.1 401 Authorization Required
       WWW-Authenticate: OAM-Auth realm="<WebGateName>:<AuthenticationLevel>
       <RelativeRESTURL>", request-ctx="<RequestContext>"
    
  3. The Mobile and Social SDK maintains a cache of Access Tokens that it has obtained during the application's lifetime. If the Access Token for this WebGate is already present in the cache, the SDK injects the Access Token into the application request.

  4. If an Access Token for the WebGate is not available in the Mobile and Social SDK cache, it sends a REST request to the Mobile and Social server to obtain the Access Token for the WebGate.

  5. If the request is valid, Mobile and Social returns an Access Token in the response.

  6. The Mobile and Social SDK injects the token returned by the Mobile and Social server and accesses the protected URL.

In version 11.1.2.2 of the SDK, an option to execute the Web service request asynchronously was added. To execute the request in the background, the SDK accepts a call back OMHTTPRequestCallback object. The SDK notifies the application when the request is executed and the REST request response is propagated to the application using this callback object. The OMHTTPRequest class receives and responds to the request. Following is the method signature.

OMHTTPRequest#executeHTTPRequest(HttpRequest httpRequest , OMHTTPRequestCallback callback , boolean isAsync)

Where:

  • httpRequest is the HttpRequest object

  • OMHTTPRequestCallback is the callback object that the SDK uses to notify the app that the request is completed. The response/error is sent using this callback object by this method:

    OMHTTPRequestCallback#processHTTPResponse(OMHTTPRequest request, HttpResponse response, OMMobileSecurityException exception)
    

    The application needs to implement this interface and handle the response/error handling logic.

  • isAsync is a Boolean that tells if the request need to be executed asynchronously or not. If false then the execution is similar to OMMobileSecurityService#processHttpRequest(HttpRequest).

Following is sample code that demonstrates an asynchronous REST request.

OMHTTPRequest omrequest1 = new OMHTTPRequest(getMobileSecuritySevice());
HttpRequest httpRequest1 = new HttpGet("http://abc.example.com:7777/restService") ;
 
try
{
omrequest1.executeHTTPRequest(httpRequest1,
new OMHTTPRequestCallback()
  {
 
    @Override
    public void processHTTPResponse( OMHTTPRequest request, HttpResponse response, OMMobileSecurityException exception)
    {
     String data1="";
     if (response != null)
      {
       try
       {
        data1 = parseHttpResponse(response);
       }
       catch (IOException e)
       {
        
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
       catch (JSONException e)
       {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }
     else
     {
       if (exception != null)
       {
        data1 = exception.getErrorMessage();
       }
     }
     if(data1 != null)
     {
       Message msg = handler.obtainMessage(MSG_SHOW_DIALOUGE);
       msg.obj = data1;
       handler.sendMessage(msg);
     }
 
   }
  }, true);
}
catch (OMMobileSecurityException e)
{
e.printStackTrace();
}

10.10 Creating a Custom Mobile Single Sign-on Agent App Using the Android Client SDK

This section covers how a custom mobile single sign-on (SSO) agent app can be created using the Android Client SDK.

When applications that are configured as SSO clients make a call to OMMobileSecurityService#authenticate(), the Android Client SDK delegates the request to the SSO agent application if it is already installed on the device. Otherwise, it throws an exception. The Android Client SDK frames the authentication request and invokes the SSO agent app using an intent. In order to process the authentication request, the SSO Agent app needs to retrieve this intent and call OMMobileSecurityService#processSSORequest(intent). The SDK internally processes and validates the authentication request and returns control back to the client app with a valid authentication context.

You can extend the Application class to keep a singleton instance for OMMobileSecurityService that accepts either a null intent or one that contains a configuration URL. The following code snippet shows how to initialize an OMMobileSecurityService instance using the configuration URL based mechanism for a new intent and using the config properties stored in SharedPreferences for subsequent cases.

public OMMobileSecurityService getMobileSecurityService(Context context,
            Intent intent, OMMobileServiceCallback callback)
            throws JSONException, OMMobileSecurityException
{
     if (!mssInitialized)
     {
            if (intent == null || intent.getData() == null)
            {
                mss = new OMMobileSecurityService(context, callback);
            }
            else
            {
                Map<String, Object> configMap = OMMobileSecurityService
                        .parseConfigurationURI(context, intent, true, null);
 
                mss = new OMMobileSecurityService(context, configMap, callback);
            }
            if (mss == null)
            {
                throw new OMMobileSecurityException(
                        OMErrorCode.INITIALIZATION_FAILED, null, context);
            }
            else
            {
                mssInitialized = true;
            }
     }
     else
     {
            mss.registerCallback(callback);
     }
     return mss;
} 

The following code snippet shows the checks that you should perform in the agent app before processing the client requests.

@Override
        protected void onResume()
        {
            super.onResume();
            mMobileSecurityService.registerActivity(this);
            if (!(SSOApplication) getApplication().isSetupCompleted())
            {
                mMobileSecurityService.setup();
            }
 
            Intent intent = getIntent();
            
            if (intent.getData() != null)
            {
                 boolean isConfigurationIntent = false;
                 /* Check if the intent URI contains the configuration parameters 
                    which can be passed to the the SSOApplication class. */ 
                 
                 if (isConfigurationIntent == true)
                 {
                      mMobileSecurityService = (SSOApplication) getApplication.getMobileSecurityService(getApplicationContext(), intent, new SSOAgentCallback();
                 }
                 else
                 {
                      mMobileSecurityService = (SSOApplication) getApplication.getMobileSecurityService(getApplicationContext(), null, new SSOAgentCallback();
                 }
            }
            if ((intent.getData() != null && !isConfigurationIntent) || intent.getExtras() != null)
            {
                try
                {
                    authView = mMobileSecurityService.processSSORequest(intent);
                    if (authView != null)
                    {
                        setContentView(authView);
                        // The developers have full control on how they want to
                        // display this view in their app.
                    }
                }
                catch (OMMobileSecurityException e)
                {
                    Log.w(TAG, e.getErrorMessage());
                }
            }
        }

Please note that you can use any design approach. The sample code is included to demonstrate the usage of the SDK.

    class SSOAgentCallback implements OMMobileServiceCallback
    {
        @Override
        public void processSetupResponse(OMApplicationProfile profile,
                OMMobileSecurityException mse)
        {
            if (profile != null)
            {
                // Setup successful you may go for authentication now
                ((SSOApplication) getApplication()).setSetupCompleted(true);
                Toast.makeText(SSOActivity.this, "Setup Done",
                        Toast.LENGTH_SHORT).show();
            }
            else
            {
                Toast.makeText(SSOActivity.this, "Setup failed",
                        Toast.LENGTH_LONG).show();
 
            }
        }
 
        @Override
        public void processAuthenticationResponse(
                OMAuthenticationContext context, OMMobileSecurityException mse)
        {
            /*
             * Handle post authentication in case of SSO self auth request, i.e.
             * when the SSO Agent app calls
             * OMMobileSecurityService#authenticate(). Note: If authentication
             * request comes from a client application , we will not get this
             * call back, as the sdk will redirect to the client app after
             * successful authentication
             */
        }
    }

10.11 Login View and KBA View Customization

The SDK displays a basic login view and knowledge-based answer view by default. To create custom user-defined layouts do the following:

  1. The OMMobileSecurityService class provides a method with the following signature:

    public void setCredentialCollector(OMAuthenticationServiceType serviceType, OMCredentialCollector viewHandler)
    

    This method can be used to set a custom view as follows:

    mobileSecurityService.setCredentialCollector(OMAuthenticationServiceType.DEVICE_AUTHENTICATION, new MyLoginView(getApplicationContext()));
    mobileSecurityService.setCredentialCollector(OMAuthenticationServiceType.KBA_AUTHENTICATION, new MyKBAView(getApplicationContext()));
    

    Follow this approach to set custom views for any of the authentication service types supported by OMAuthenticationServiceType.

  2. MyLoginView is a custom class that implements the OMCredentialCollector interface. The custom view to be displayed by the SDK has to be returned from this method:

    OMCredentialCollector#processViewRequest(Map<String, String> inputParams, OMCredentialCollectorCallback callback)

    Write this method to collect a user name and password or security answer, then pass these values to the SDK. Put the values in an object of type Map<String, String> and pass the object to the SDK using callback.processLoginResponse(Map<String, String>).

    For Log in View customization, use the following keys for the user name and password values:

    OMSecurityConstants.USERNAME
    OMSecurityConstants.PASSWORD 
    

    For KBA View customization, use the following key for the security answer:

    OMSecurityConstants.ANSWER_STR
    

    If any exception happens in a request, the SDK will populate it in the inputParams map, which is an input parameter to the following method:

    OMCredentialCollector#processViewRequest(Map<String, String> inputParams, OMCredentialCollectorCallback callback)
    

    Design the custom view such that, if the SDK sends an error message, it should be shown in the view. Use the following key to obtain the error message:

    OMSecurityConstants.ERROR_MESSAGE
    

    For the KBA view, the question will be available as part of the inputParams map with the key as follows:

    OMSecurityConstants.QUESTION_STR
     
    

    Define OMCredentialCollector#processViewRequest(Map<String, String> inputParams, OMCredentialCollectorCallback callback) such that it will retrieve the question from the inputParams map and display the question in the view.

    Refer to the following sample code for Log in View customization:

    class MyLoginView implements OMCredentialCollector
    {
        ...
        @Override
        public View processViewRequest(Map<String, String> inputParams, OMCredentialCollectorCallback callback)
        {
            // Create the basic auth view
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            basicAuthView = inflater.inflate(R.layout.mybasicauth, null);
     
            ...
            // You can enable username and password EditText Views, which may be disabled when the log in button is pressed
     
            Button button = (Button) basicAuthView.findViewById(R.id.login);
            button.setOnClickListener(new AuthenticationLoginListener(callback));
     
            Button cancelButton = (Button) basicAuthView.findViewById(R.id.cancel);
            cancelButton.setOnClickListener(new AuthenticationCancelListener(context, callback));
     
            String errorMsg = inputParams.get(ERROR_MESSAGE);
            TextView errorMsgTv = (TextView) basicAuthView.findViewById(R.id.errorMsg);
            if (errorMsg != null && !errorMsg.isEmpty())
            {
                errorMsgTv.setVisibility(View.VISIBLE);
                errorMsgTv.setText(errorMsg);
            }
            else
            {
                errorMsgTv.setVisibility(View.INVISIBLE);
            }
            inputParams.remove(ERROR_MESSAGE);
     
            return basicAuthView;
        }
        //-------------------------------------------------------------------------
        // Inner class which handles the OnClick event
        //-------------------------------------------------------------------------
     
        private class AuthenticationLoginListener implements OnClickListener
        {
            OMCredentialCollectorCallback callback;
     
            AuthenticationLoginListener(OMCredentialCollectorCallback callback)
            {
                this.callback = callback;
            }
     
            @Override
            public void onClick(View v)
            {
                // The developer may show a progress bar and disable the Login and Cancel buttons
                Map<String, String> outputParams = new HashMap<String, String>();
     
                outputParams.put(USERNAME, username);
                outputParams.put(PASSWORD, password);
     
                basicAuthView.invalidate();
     
                callback.processLoginResponse(outputParams);
            }
        }
    }
    // This class is a part of the samples for both Login View and KBA View 
    // Customization
     
    class AuthenticationCancelListener implements OnClickListener
    {
        private OMCredentialCollectorCallback callback;
        private Context context;
     
        AuthenticationCancelListener(Context context, OMCredentialCollectorCallback callback)
        {
            this.context = context;
            this.callback = callback;
        }
     
        @Override
        public void onClick(View view)
        {
            callback.processCancelResponse();
        }
    }
    

    Sample code for KBA View customization has been given below:

    class KBAView implements OMCredentialCollector
    {
        ...
        @Override
        public View processViewRequest(Map<String, String> inputParams,
                OMCredentialCollectorCallback callback)
        {
            // Create the view for KBA
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     
            kbaAuthView = inflater.inflate(R.layout.mykbaview, null);
     
            Button button = (Button) kbaAuthView.findViewById(R.id.casubmit);
            button.setOnClickListener(new AuthenticationLoginListener(callback));
     
            Button cancelButton = (Button) kbaAuthView.findViewById(R.id.cacancel);
            cancelButton.setOnClickListener(new AuthenticationCancelListener(
                    context, callback));
     
            TextView question = (TextView) kbaAuthView.findViewById(R.id.cques);
            question.setText(inputParams.get(QUESTION_STR));
     
            return kbaAuthView;
        }
     
        //-------------------------------------------------------------------------
        // Inner class which handles the OnClick event
        //-------------------------------------------------------------------------
     
        private class AuthenticationLoginListener implements OnClickListener
        {
            OMCredentialCollectorCallback callback;
     
            AuthenticationLoginListener(OMCredentialCollectorCallback callback)
            {
                this.callback = callback;
            }
     
            @Override
            public void onClick(View v)
            {
               // You can show a progress bar and disable the submit and 
               // cancel buttons
     
                String answer = chalngAns.getText().toString();
                Map<String, String> outputParams = new HashMap<String, String>();
                outputParams.put(ANSWER_STR, answer);
     
                callback.processLoginResponse(outputParams);
            }
        }
    }
    

10.12 Using the Cryptography APIs

This section covers the cryptography APIs that are exposed by the SDK. The SDK uses these APIs to protect and store credentials for offline authentication. For detailed information about API methods, please refer to the API documentation included in the SDK download.

OMCryptoService is the class that supports all of the features like hashing, encryption, decryption, and matching whose instance can be obtained using mss as follows:

OMCryptoService cryptoService =  mss.getCryptoService();
 

Note:

In the 11.1.2.2 release, the OMCryptoService added support for passing a custom key for features such as encryption, decryption, and matching, while keeping support for legacy features that work independent of any key. Applications can now manage the life cycle of the crypto key themselves. They do not have to depend on the SDK generated key. It is the application's duty to provide the same key for encryption and decryption of the same data. The custom key that the SDK accepts is a byte[] array. The application must provide a compliant key size based on the encryption algorithm being used.

Following is a high-level summary of the functionality provided by the cryptography API.

Hashing

Use the hashing capability to produce a hash of plain text based on the crypto scheme algorithm. If it is a salted algorithm, then it uses the salt length that is given as input. The last parameter in the API determines whether to prefix the algorithm name.

The output is of the following format:

<Algorithm Name><HashedContent><Salt>

  • The hashed content and salt are Base-64 encoded.

  • The algorithm name will be prefixed only if it is requested.

  • The salt will be present only if the algorithm is a salted algorithm.

cryptoService.hash(plainText, scheme, 10, true);

Symmetric Key Encryption

This API helps perform symmetric key encryption and decryption of data. The key used for encryption is either generated automatically and stored in the credential store (the SDK default key), or a custom key provided by the application.

The output of encryption is of the following format:

<scheme/mode/padding> <Initialization Vector><Encrypted text>:

Both the initialization vector and the encrypted text are Base-64 encoded. The initialization vector will be used later for decryption as well.

cryptoService.encrypt(plainText, scheme, msc.getCryptoMode(), msc.getCryptoPadding(), true);

If using a custom key:

cryptoService.encrypt(plainText, scheme, msc.getCryptoMode(), msc.getCryptoPadding(), true, customKey);

The key for decryption is automatically retrieved from the credential store automatically (that is, the SDK default Key), or provided by the application if the encryption was done using a custom key. The decrypted text is given as output by the following method. The SDK default key is generated automatically by the SDK when the encrypt method is called for the first time.

cryptoService.decrypt(encodedText);

If using a custom key:

cryptoService.decrypt(encodedText,customKey);URL

Matching of Plain Text and Encrypted/Hashed Text

The following method will check the encoded text given as input and find the oracle.idm.mobile.crypto.CryptoScheme that was used to encrypt or hash it. If it was encrypted, it will decrypt the encoded text and check whether it matches with plain text. It it was hashed, it will perform hashing on the plain text and check whether it matches with the encoded text. Depending on the match, it will return true or false.

Note:

If the text is encrypted using a custom Key, the application should pass the same key in the match() method.
cryptoService.match(password, passwordStored, mss.getMobileSecurityConfig().getSaltLength());

If using a custom key:

cryptoService.match(password, passwordStored, mss.getMobileSecurityConfig().getSaltLength(), customKey);

10.13 Using the Auto Login and the Remember Credentials Features

The Mobile and Social Android Client SDK provides APIs that can securely store user credentials and play them back to a login server with or without user interaction. Deploy this feature in apps where security is not critically important to make it easier for users to log in. This feature requires at least version 11.1.2.2.0 of the Mobile and Social Client SDK.

To use this feature, the user selects one of up to three option boxes on the login screen. (You can choose to enable one, two, or all three of these options in your app.) If more than one option is selected, the higher priority feature takes precedence. The priority of the options is as follows:


1. Auto Login
2. Remember Credentials
3. Remember User Name Only

So for example, if Auto Login and Remember Credentials are selected, then Auto Login takes priority.

The three options are described as follows:

  • Auto Login - The Mobile and Social Android Client SDK securely caches the user's credentials and automatically supplies them at the login screen. This option does not require any user interaction to log the user in. The user see a progress screen that provides feedback while authentication is underway.

  • Remember Credentials - The Mobile and Social Android Client SDK securely caches the user's credentials and auto-fills the user name and password fields on the login screen. The user has to click the Login button to proceed with the authentication process. The user can enter different credentials and make changes to the option boxes if necessary.

  • Remember User Name Only - The Mobile and Social Android Client SDK securely caches the user name and auto-fills the user name on the login screen. The user has to input the password and click the login button to proceed with the authentication process. The user can enter different user name and make changes to the option boxes if necessary.

Enabling the Feature

This is a client-side only feature that does not require server configuration to deploy. To enable the features described, the following SDK configuration parameters should be added to your code:

Table 10-7 Configuration parameters used to enable auto login and remember credentials features

Parameter Description

OM_PROP_AUTO_LOGIN_ALLOWED

Boolean value that enables/disables the Auto Login feature.

OM_PROP_REMEMBER_CREDENTIALS_ALLOWED

Boolean value that enables/disables the Remember Credentials feature.

OM_PROP_REMEMBER_USERNAME_ALLOWED

Boolean value that enables/disables the Remember User Name Only feature.


Handling User Preferences

Pass the following properties while initializing the mss object to pre-populate the option boxes with a default value. Only one of the following options can be true. If all the option box states are false, all of the option boxes on the login screen will be empty.

Table 10-8 Configuration parameters used to set the option box default values

Parameter Description

OM_AUTO_LOGIN_DEFAULT

Boolean value that specifies the default value of the "Auto Login" option box.

OM_REMEMBER_CREDENTIAL_DEFAULT

Boolean value that specifies the default value of the "Remember Credential" option box.

OM_REMEMBER_USERNAME_DEFAULT

Boolean value that specifies the default value of the "Remember User Name Only" option box.


Persist option box states as key-value pairs in SharedPreferences. Use the combination of the server URL and the application identifier as a key so that the user preferences for each login connection can be uniquely identified.

Clearing Credentials and Preferences From Mobiles Devices

Authentication failure can result if the user credentials were changed since the last login, or if the mobile device is not able to reach the authentication service due to a network or server issue. If authentication fails using the stored credentials, the SDK deletes the stored password (if present) from the shared preferences. The login page will then either revert to the Remember User Name Only feature, or control will revert to the mobile app using OMMobileServiceCallback. This decision is based on an SDK-level parameter named OM_PROP_MAX_LOGIN_ATTEMPTS, which is a numeric value that stores how many incorrect attempts for authentication are allowed before control is given back to the mobile app.

The SDK will clear a stored user password from the mobile device in the following scenarios:

  • The user authentication fails (for example, if the server password is no longer valid, the user is blocked, or if the user authentication fails for another reason).

  • The Mobile and Social Android Client SDK logout method is called

  • A session time-out is detected

The SDK will clear the stored user name, password, and option box states from the mobile device in the following scenario:

  • The Mobile and Social Android Client SDK logout method is called and the forgetDevice parameter is set to true

Creating a Custom Login Screen

The Mobile and Social Android Client SDK sends flags in the input params map in the processViewRequest callback that you use to inflate your custom views. (See Section 10.11, "Login View and KBA View Customization" for more information.) These flags are specific to the Auto Login and Remember Credentials features and indicate if a given feature is enabled or disabled during initialization, and what the UI preference for these features should be set to. The SDK also sends the user name and the password as needed for the Remember User Name and Remember Credentials options.

If you want to create a custom login screen instead of using the basic login view provided by the SDK, do the following:

  • Receive and interpret the Auto Login / Remember Credentials flags correctly

  • Control the visibility of the option boxes for flags that indicate if a feature is enabled

  • For flags that indicated UI preferences, update the state of the option boxes when presenting the view to the user

  • After the submit button is pressed, read the state of the option boxes and send the same

The following table lists the keys that you need to use to access credential properties in the authentication inputParams Map.

Table 10-9 Keys used to access credential properties in the inputParams Map

Key Description

OMMobileSecurityService.OM_PROP_AUTO_LOGIN_ALLOWED

Boolean value that enables/disables the Auto Login feature.

OMMobileSecurityService.OM_PROP_REMEMBER_CREDENTIALS_ALLOWED

Boolean value that enables/disables the Remember Credentials feature

OMMobileSecurityService.OM_PROP_REMEMBER_USERNAME_ALLOWED

Boolean value that enables/disables the Remember User Name Only feature

OMSecurityConstants.OM_AUTO_LOGIN_PREF

Boolean value that specifies the user's preference regarding the Auto Login feature based on the last authentication.

OMSecurityConstants.OM_REMEMBER_CREDENTIALS_PREF

Boolean value that specifies the user's preference regarding the Remember Credentials feature based on the last authentication.

OMSecurityConstants.OM_REMEMBER_USERNAME_PREF

Boolean value that specifies the user's preference regarding the Remember User Name Only feature based on the last authentication.

OMSecurityConstants.USERNAME

String value that specifies the user's user name.

OMSecurityConstants.PASSWORD

String value that specifies the user's password.


The following code sample shows how you can control the visibility and UI state of the option boxes using the remember credentials flags.

// RC
CheckBox autoLogin = (CheckBox) basicAuthView.findViewById(R.id.autoLoginCB);
CheckBox rememberCredentials = (CheckBox) basicAuthView.findViewById(R.id.rememberCredentialsCB);
CheckBox rememberUsername = (CheckBox) basicAuthView.findViewById(R.id.rememberUsernameCB);
// RC
button.setOnClickListener(new AuthenticationLoginListener(callback));
 
Button cancelButton = (Button) basicAuthView.findViewById(R.id.cancel);
cancelButton.setOnClickListener(new AuthenticationCancelListener(asm,callback));
 
EditText username = (EditText) basicAuthView.findViewById(R.id.username);
username.setEnabled(true);
EditText password = (EditText) basicAuthView.findViewById(R.id.password);
password.setEnabled(true);
String usernameFromRCStore = null;
String passwordFromRCStore = null;
String identityFromRCStore = null;
boolean rcUseCase = false;
// Try to get the user name or password stored by the SDK.
// Note: This is possible only if the Remember Credentials feature is
// enabled.
if (inputParams.containsKey(USERNAME))
{
  usernameFromRCStore = (String) inputParams.get(USERNAME);
}
if (inputParams.containsKey(PASSWORD))
{
  passwordFromRCStore = (String) inputParams.get(PASSWORD);
}
 
Object autoLoginAllowedObj = inputParams.get(OMMobileSecurityService.OM_PROP_AUTO_LOGIN_ALLOWED);
if (autoLoginAllowedObj != null)
{
  boolean autoLoginAllowed = ((Boolean) autoLoginAllowedObj);
  // feature enabled now set the visibility to true.
  if (autoLoginAllowed)
  {
    autoLogin.setVisibility(View.VISIBLE);
    Object alChecked = inputParams.get(OMSecurityConstants.OM_AUTO_LOGIN_PREF);
    if (alChecked != null)
    {
      autoLogin.setChecked((Boolean)alChecked);
    }
    rcUseCase = true;
  }
}
 
Object remCredObj = inputParams.get(OMMobileSecurityService.OM_PROP_REMEMBER_CREDENTIALS_ALLOWED);
if (remCredObj != null)
{
  boolean rememberCredentialsAllowed = ((Boolean) remCredObj);
  if (rememberCredentialsAllowed)
  {
    // feature enabled now set the visibility to true.
    rememberCredentials.setVisibility(View.VISIBLE);
    Object rcChecked = inputParams.get(OMSecurityConstants.OM_REMEMBER_CREDENTIALS_PREF);
    if (rcChecked != null)
    {
      rememberCredentials.setChecked((Boolean)rcChecked);
    }
    rcUseCase = true;
  }
}

Object remUserObj = inputParams.get(OMMobileSecurityService.OM_PROP_REMEMBER_CREDENTIALS_ALLOWED);
if (remUserObj != null)
{
  boolean rememberUsernameAllowed = ((Boolean) remUserObj);
  if (rememberUsernameAllowed)
  {
    // feature enabled now set the visibility to true.
    rememberUsername.setVisibility(View.VISIBLE);
    Object ruChecked = inputParams.get(OMSecurityConstants.
OM_REMEMBER_USERNAME_PREF);
    if (ruChecked != null)
    {
      rememberUsername.setChecked((Boolean)ruChecked);
    }
    rcUseCase = true;
  }
}
// pre filling
if (rcUseCase)
{
  if (usernameFromRCStore != null && usernameFromRCStore.length() > 0)
  {
    username.setText(usernameFromRCStore);
  }
  if (passwordFromRCStore != null && passwordFromRCStore.length() > 0)
  {
    password.setText(passwordFromRCStore);
  }
}
// RC
 

This next code sample shows how to control the visibility and UI state of the option boxes when the submit (or log on) button is pressed.

// Do the registration and then perform the authentication
EditText username = (EditText) basicAuthView.findViewById(R.id.username);
username.setEnabled(false);
 
EditText password = (EditText) basicAuthView.findViewById(R.id.password);
password.setEnabled(false);

 
Button button = (Button) basicAuthView.findViewById(R.id.login);
button.setEnabled(false);
 
Button cancelButton = (Button) basicAuthView.findViewById(R.id.cancel);
cancelButton.setEnabled(false);
// RC
CheckBox autoLogin = (CheckBox) basicAuthView.findViewById(R.id.autoLoginCB);
CheckBox rememberCredentials = (CheckBox) basicAuthView.findViewById(R.id.rememberCredentialsCB);
CheckBox rememberUsername = (CheckBox) basicAuthView.findViewById(R.id.rememberUsernameCB);
// RC
InputMethodManager imm = (InputMethodManager) asm.getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(username.getWindowToken(), 0);
 
String uname = username.getText().toString();
String pwd = password.getText().toString();
 
Map<String, Object> outputParams = new HashMap<String, Object>();
//sending the username passord for the authentication purpose.
outputParams.put(USERNAME, uname);
outputParams.put(PASSWORD, pwd);
// RC
//sending UI preferences for the current auth /login screen to the SDK 
outputParams.put(OMSecurityConstants.OM_AUTO_LOGIN_PREF,autoLogin.isChecked());
outputParams.put(OMSecurityConstants.OM_REMEMBER_CREDENTIALS_PREF,rememberCredentials.isChecked());
outputParams.put(OMSecurityConstants.OM_REMEMBER_USERNAME_PREF,rememberUsername.isChecked());
// RC
 
basicAuthView.invalidate();
 
callback.processLoginResponse(outputParams);

10.14 Invoking the CredentialStoreService With the Android Client SDK Secure Storage Module

The SDK CredentialStoreService stores and retrieves sensitive data. Internally, the SDK uses the SharedPreferences class provided in the Android SDK. For more information, see the following Web page:

http://developer.android.com/reference/android/content/SharedPreferences.html

Start using CredentialStoreService by getting a reference to an instance of OMCredentialStore using OMMobileSecurityService#getCredentialStoreService(). Once the reference to CredentialStoreService is obtained, credentials can be added, updated, deleted, or read from the Credential Store. Please refer to the SDK documentation for more details.

Following is a sample snippet of code illustrating the usage:

OMCredentialStore credentialStore = mss.getCredentialStoreService();
credentialStore.addCredential("sampleKey", "sampleUsername", "samplePassword", "sampleTenantName", properties);
// properties is a Map<String, String>. This method will convert all the
// parameters like username, password, tenant name and properties into a JSON
// string and store the same in CredentialStore
OMCredential credential = credentialStore.getCredential("sampleKey");
// This method will retrieve the credential information on supplying the correct
// key
        

10.15 Error Codes

This section describes the error codes and messages that are thrown by the Android Client SDK. The error codes and corresponding messages are coded as an enum and exposed as a public API.

Table 10-10 Mobile and Social Android Client SDK Error Codes and Messages

Error Code Description

COULD_NOT_CONNECT_TO_SERVER(1, "Could not establish a connection to the server.")

This exception is thrown when the SDK cannot connect to the server. This may occur because of a URISyntaxException, an IllegalArgumentException, and so on.

CHALLENGE_INVALID(2, "Challenge answer is invalid.")

This exception is thrown when the user does not provide a challenge answer in the case of knowledge-based authentication (KBA).

UN_PWD_INVALID(3, "Username and Password is invalid.")

This exception is thrown when the user does not provide a user name and password in the UI before executing the authentication call with the server, as well as when the response from the server is 401 Unauthorized.

TOKENS_NOT_MATCHED(4, R.string.tokensNoMatch)

This exception is thrown if the required tokens that you requested are not present in the tokens returned by the server.

COULD_NOT_PARSE_RESPONSE_FROM_SERVER(5, "Could not parse the response sent from the server.")

This exception is thrown when the HttpResponse from the server cannot be parsed by the SDK.

DEVICE_NOT_AUTHENTICATED(6, "This device is not yet authenticated with Mobile and Social Server.")

This exception is thrown when the authentication with RestAuthenticationService finds out that the device registration token is not found.

USER_CANCELED_CERTIFICATE(7, R.string.certificateNotAccepted)

This exception is thrown if the untrusted SSL certificate is rejected by the user.

NO_AUTHENTICATION_SCHEME(8, "No authentication scheme is specified.")

This exception is thrown when there is no authentication scheme provided in the mobile security configuration object.

INVALID_BASIC_AUTH_URL(9, R.string.invalidBasicUrl)

This exception is thrown if the supplied authentication URL is not valid.

USER_AUTHENTICATION_FAILED(10, "Authentication request failed for user %1$s.")

This exception is thrown when the user authentication fails due to some internal errors from the server.

UN_PWD_TENANT_INVALID(11, R.string.unPwdTenantMissing)

This exception is thrown if authentication is not successful due to an incorrect user name or password.

UNABLE_TO_OPEN_RP_AUTHENTICATION_URL(12, "Unable to open RP Authentication URL.")

This exception is thrown when the SDK is not able to construct a valid RP login URL.

UNABLE_TO_OPEN_SSO_AUTHENTICATION_URL(13, "Unable to open SSO Authentication URL.")

This exception is thrown when the business application is not able to open an SSO agent application because it might not have been installed on the device. Another possible reason is that the Android Application signatures entered in the Application Profiles of the SSO Agent and the SSO Client on the server do not match the signatures of the SSO Agent and SSO Client installed on the device.

NOT_AUTHORIZED_TO_PARTICIPATE_IN_SSO(14, "Client application is not authorized to participate in SSO.")

This exception is thrown when the business application is not able to self-authenticate or is not able to participate in SSO. This is due to an invalid configuration in the server console.

SETUP_FAILED_MS(16, "Application profile cannot be downloaded due to missing configuration")

This exception is thrown when the application profile cannot be downloaded from the Mobile & Social Server. This happens when the server URL, application ID, or service domain is null or empty.

TOKENS_NOT_AVAILABLE(17, R.string.tokensNotAvailable)

This exception is thrown if the OAM_ID token is not available when accessing a protected URL through a browser that is configured to invoke the SSO agent app for authentication. This may result if the authentication scheme is not set as MobileOAMAuthentication.

SETUP_NOT_INVOKED(21, "Setup API is not invoked.")

This exception is thrown when the setup() method of the SDK is not invoked.

SERVICE_DOMAIN_MISMATCH(22, "Authentication is rejected by the agent as the service domain does not match.")

This exception is thrown when the service domain of the SSO application does not match the service domain of the SSO client application.

USER_NOT_YET_AUTHENTICATED(23, "The user is not yet authenticated.")

This exception is thrown when the user is trying to execute processHttpRequest() to access a resource before authenticating.

APP_SIGNATURE_INVALID(24, "Failed in validating calling application signature.")

This exception is thrown when the SSO application is not able to validate the application signature of the calling business application.

INITIALIZATION_FAILED(25, "Initialization of the SDK failed, as the required server information is not supplied.")

This exception is thrown when any application is initialized through the URL scheme and the appropriate fields are not supplied.

INTERNAL_ERROR(26, "Internal Error")

This exception is thrown for all other exceptions raised from the SDK.