Skip navigation links

Package com.microfocus.android.mobile.sdk.library

Microfocus Android Mobile SDK

See: Description

Package com.microfocus.android.mobile.sdk.library Description

Microfocus Android Mobile SDK

Index

Integrating a new native Android application with the SDK
    Understanding, initializing, and using the ServiceContext interface
    Creating an Identity Provider instance
    Using an Authenticator to authenticate an end user
    Obtaining an existing OAuth2 access token without authenticating
    Required client application AndroidManifest.xml entry
    Performing an asynchronous action, like invoking a URL, with a fresh access token

Integrating a new native Android application with the SDK

To successfully use the SDK, client application developers must be familiar with the following SDK classes and interfaces:
ServiceContextFactory
Provides a single method getInstance() to obtain an ServiceContext.
ServiceContext
The main provider of SDK functionality. All roads start here.
IdentityProvider
A description of an OAuth2 Identity Provider service. Required to indicate where authentication will take place.
IdentityProviderBuilder
A builder of IdentityProvider instances. Obtained from the ServiceContextFactory interface.
Authenticator
Performs a single authentication and provides an AuthenticatorReport back to the client application that details the authentication status, and tokens.
AuthenticatorBuilder
A builder of Authenticator instances. Obtained from the ServiceContext interface.
AuthenticatorClientCallback
A callback invoked by the SDK at the completion of an authentication. Must be implemented in the client code by the SDK integrator.
AuthenticatorReport
Details authentication status, errors, and tokens. Indicates what OAuth2 profile(s) were invoked during the authentication process. Provided to the client application as a parameter to the AuthenticatorClientCallback callback mechanism.
UnAuthenticator
Performs a single un-authentication (logout) and provides an UnAuthenticatorReport back to the client application that details the un-authentication status.
UnAuthenticatorBuilder
A builder of UnAuthenticator instances. Obtained from the ServiceContext interface.
UnAuthenticatorClientCallback
A callback invoked by the SDK at the completion of an un-authentication. Must be implemented in the client code by the SDK integrator.
UnAuthenticatorReport
Details un-authentication status and error(s). Indicates what actions were invoked during the un-authentication process. Provided to the client application as a parameter to the UnAuthenticatorClientCallback callback mechanism.

Understanding, initializing, and using the ServiceContext interface

The glue that connects the client application with the SDK is the ServiceContext object. This object will be used to get builders, persist objects, access settings, and perform actions. For most SDK functionality, this is the class that will provide the starting point.

An instance of a ServiceContext may be obtained by calling the ServiceContextFactory.getInstance() static method. After the first time it is called, there is little overhead in repeatedly calling the getInstance() method, so caching the returned reference is not required. It is expected that client application code will have many calls to getInstance().

     ServiceContext svcContext = ServiceContextFactory.getInstance();
     ... Make calls using the context
 
The first implementation item that must be done in client application code is to initialize the ServiceContext instance. This object must follow the lifecycle of the client application's main Android activity. To accomplish this, add calls into the ServiceContext object from the client Android application's main activity lifecycle methods onStart(), onPause(), onResume() and onStop().
    protected void onStart() {
       super.onStart();
       ServiceContextFactory.getInstance().onStart(this);
       ..... Additional handling
    }

    protected void onResume() {
       super.onResume();
       ServiceContextFactory.getInstance().onResume();
       ..... Additional handling
    }

    protected void onPause() {
       super.onPause();
       ServiceContextFactory.getInstance().onPause();
       ..... Additional handling
    }

    protected void onStop() {
       super.onStop();
       ServiceContextFactory.getInstance().onStop();
       ..... Additional handling
    }
 

Creating an Identity Provider instance

The second task for client application implementations is to allow the end user to define an Identity Provider. In the SDK, an Identity Provider is defined as a description of an OAuth2/OpenIdConnect service available over HTTPS end points. It is the responsibility of the client implementation to gather the data required to build an IdentityProvider object.

Once the Identity Provider data has been gathered, obtain an IdentityProviderBuilder and instantiate an IdentityProvider instance as follows:

     IdentityProviderBuilder builder =
             ServiceContextFactory.getInstance().getIdentityProviderBuilder(...);

     ... call additional builder setters if necessary

     IdentityProvider identityProvider = builder.build();
 
The ServiceContextFactory provides multiple versions of the getIdentityProviderBuilder method. Please see the JavaDoc describing each of the methods to decide which signature is appropriate.

ServiceContext.getIdentityProviderBuilder(String providerUrl, String clientId, String clientSecret, String redirectURI)
ServiceContext.getIdentityProviderBuilder(String json)
ServiceContext.getIdentityProviderBuilder(IdentityProvider source)

Once an IdentityProvider instance is obtained, it may be persisted to the application storage as follows:

    ServiceContextFactory.getInstance().putIdentityProvider(
                                                       Context context,
                                                       IdentityProvider identityProvider);
 
Only one IdentityProvider instance may be persisted at a time. All authentication and un-authentication operations use the currently persisted IdentityProvider. Attempting to authenticate or un-authenticate without having a persisted IdentityProvider will result in an exception.

Using an Authenticator to authenticate an end user

Once an IdentityProvider instance is persisted, then the client application can authenticate the end user using the described IdentityProvider. A typical client side authentication implementation looks like this:
    private class ClientAuthenticatorCallbackImpl
        implements AuthenticatorCallback
    {
        public void onAuthenticationComplete (AuthenticatorReport report)
        {
            if (report.isAuthenticated())
            {
                String accessToken = report.getAccessToken();

                ... Do something with the access token

                // Note that in this case there still may exist an exception if the refresh token
                // was expired. If an access token refresh was attempted and failed because the
                // refresh token was expired then an exception will be logged under the access token
                // refresh category. However, the authentication could still be successful because
                // an automatic complete re-authentication would be initiated, and may be
                // successful.
            }
            else if (report.existsAnyExceptions())
            {
                ... Get the exception and display an end user message
            }

            // Check to see if the Identity Provider was updated
            if ((report.identityProviderConfigurationRefreshInitiated()) &&
               (null == report.getIdentityProviderConfigurationRefreshExceptions()))
            {  // The identity provider changed due to a successful discovery,
               // update the client's cached copy of the Identity Provider to match the new
               // persisted Identity Provider.
                myClientIdentityProvider = report.getIdentityProvider()
            }
        }
    }

    Authenticator authenticator =
         ServiceContextFactory.getInstance().getAuthenticatorBuilder(context,
                                                                     identityProvider.getHost(),
                                                                     identityProvider.getClientId(),
                                                                     new ClientAuthenticatorCallbackImpl())
                                                                     .build();

    ServiceContextFactory.getInstance().authenticate(authenticator);
 
The ServiceContextFactory.getInstance().authenticate(authenticator) call may return immediately with an exception. Generally, if this method throws an exception, then the AuthenticatorClientCallback will not be called and the client code must clean up after the failed authentication.

If ServiceContextFactory.getInstance().authenticate(authenticator) does not throw an exception, then it can be assumed that the AuthenticatorClientCallback will be called and client code must react to the end of the authentication in that callback.

If an IdentityProvider has not been persisted, then the ClientAuthenticatorCallbackImpl will be called with a AuthenticatorException.IDENTITY_PROVIDER_NOT_RESOLVABLE exception.

Generally, once the client application code calls the SDK to persist an IdentityProvider instance, the SDK will not alter the IdentityProvider content. However, there is one case where the SDK may alter the IdentityProvider content. If the SDK performs an OAuth2 Identity Provider Discovery request and receives metadata describing the IdentityProvider, then the SDK will automatically persist (update) the currently persisted IdentityProvider with the metadata information.

In this scenario, the client code may want to update their copy of the IdentityProvider with the newly discovered data. To do this, the client code would place code inside the AuthenticatorClientCallback.onAuthenticationComplete(com.microfocus.android.mobile.sdk.library.AuthenticatorReport) method that checks AuthenticatorReport.identityProviderConfigurationRefreshInitiated() for a true return. In this case, the IdentityProvider supplied by the AuthenticatorReport contains the updated data and is provided so that clients may use that instance as their new "cached" copy of the IdentityProvider.

Please see the above code fragment for an example of how to determine if the IdentityProvider was updated and how to get the new instance.

Authentication may be a very heavy weight process if no OAuth2 refresh token exists. In this case, the user may be required to enter credentials at the Identity Provider as part of a full authentication. A middle ground exists where the OAuth2 access token is expired and must be refreshed. On the other extreme, authentication may be a very light weight operation if a valid OAuth2 access token already exists. In this case, the authentication process simply determines that the access token is still valid and provides it back to the client inside of the AuthenticatorReport object.

Obtaining an existing OAuth2 access token without authenticating

It is recommended that client implementations use the ServiceContext.authenticate(Authenticator) method to obtain tokens because it automatically ensures the tokens are fresh and provides all user interaction if tokens need to be updated. There is, however, another, more direct, way to get an access token.
    long somePreDeterminedTime = (20 * DateTimeUtil.SECOND_IN_MILLIS);
    long millisecondsToExpiration = ServiceContextFactory.getInstance().getTimeToAccessTokenExpiration(AuthenticateActivity.this, identityProvider);
    if (somePreDeterminedTime < millisecondsToExpiration)
    {
        String accessToken = ServiceContextFactory.getInstance().getAccessToken(context, identityProvider);
        ... Do something with the access token that is sure to take less than somePreDeterminedTime
    }
 

Required client application AndroidManifest.xml entry

The client application AndroidManifest.xml file must have an entry defining the activity to invoke to resolve the OAuth2 authorization code. The entry must be identical to the entry below except the client application integrator must provide the <data> element's attribute values, android:scheme, android:host, and android:path, to reflect their Identity Provider's redirect URL.
     <activity android:name="net.openid.appauth.RedirectUriReceiverActivity">
         <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="someclientscheme"
                   android:host="someclienthost"
                   android:path="someclientpath"/>
         </intent-filter>
     </activity>

Performing an asynchronous action, like invoking a URL, with a fresh access token

The ServiceContext.invokeWithFreshToken() method provides asynchronous execution of a client implemented task. Generally, it is expected that client HTTP requests will be made using this mechanism.

To use this method: 1) Create a sub-class of InvokeTask that performs the desired operation. The sub-class may use the optional InvokeClientCallback mechanism to be notified of the task completion or it may forgoe the callback if all "completion" code may be implemented in the task's onPostExecute() method. 2) Invoke the method with a new instance of the InvokeTask.

This method will check the expiration time of any existing access token and may contact the OAuth2 server to obtain a newly minted token. It will then set the access token into the InvokeTask instance and then call its execute() method.

For complete details please refer to the JavaDoc headers for the following:
com.microfocus.android.mobile.sdk.library.ServiceContext.invokeWithFreshToken(android.content.Context, com.microfocus.android.mobile.sdk.library.InvokeTask, long)
InvokeTask InvokeClientCallback

Skip navigation links