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:
Section 10.2, "Invoking Authentication Services With the Android Client SDK"
Section 10.3, "Alternate Approach to Initializing the Android Client SDK"
Section 10.5, "Invoking Relying Party Authentication Using the Android Client SDK"
Section 10.6, "Invoking the Mobile Single Sign-on Agent App"
Section 10.7, "Invoking User Profile Services With the Android Client SDK User Role Module"
Section 10.9, "Creating a Custom Mobile Single Sign-on Agent App Using 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 four 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.
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:
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: Initialize Required Objects and Declare the Endpoints
Create an object of OMMobileSecurityService
as follows by providing the required Mobile and Social server details.
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 an "Internet Identity Authentication" authentication scheme.
OMMobileSecurityService mss = OMMobileSecurityService(context, serverUrl, applicationId, serviceDomain, callback);
The context
argument is the context of the Application
object. Pass the context that is returned by Context#getApplicationContext()
.
Note:
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.
The serverUrl
argument is the URL (including protocol, host name, and port number) required to reach the Mobile and Social server. Only the HTTP and HTTPS protocols are supported.
The applicationId
argument is 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.
The serviceDomain
argument specifies the name of the service domain that has been created on the Mobile and Social server. The application profile that the applicationId
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.
The callback
argument 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()
and OMMobileSecurityService#authenticate()
.
Be sure to register the current activity before invoking certain methods in the OMMobileSecurityService
, such as setup()
, authenticate()
, authenticate(String userName, char[] password
,
OMAuthenticationRequest authRequest
, String credentialKey)
, processSSORequest(Intent intent)
, and processHttpRequest(Intent intent)
. Deregister the activity when it is not in the foreground. Do this to ensure that there are no memory leaks. To give the reference to the current activity, register the current activity in onResume()
and deregister the activity in onPause()
for activities that call the methods mentioned previously. If you call any of these methods in onCreate()
of the activity, register the activity before calling these methods. To deregister the activity, when the activity moves to the background, use the OMMobileSecurityService#deregisterActivity()
method.
mss.registerActivity(this);
Next, call the OMMobileSecurityService
setup
method.
mss.setup();
The setup
method gets the configured security policies and the application profile from the Mobile and Social server. This method also gets a list of the service endpoints (the URLs) that are required for connecting to the authentication, authorization, and user profile services on the Mobile and Social server.
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 calling callback.processSetupResponse(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.
The following table lists the standard Application Profile attributes that you define on the Mobile and Social server. The SDK parses and stores these attributes after downloading the Application Profile.
Table 10-1 Configuration Attributes
Attribute | Description |
---|---|
Access Service URL |
The URL used to obtain access tokens from the Oracle Access Management server. |
Allow Offline Authentication |
Indicates if offline authentication should be allowed or not. |
Android Application Signature |
Signature of the Android application. |
Claim Attributes |
A comma separated string that represents the names of the various attributes that should be collected from the device as part of the identity claims. |
Credential Level for Registration of Application |
In the context of Mobile Single Sign-on, this specifies whether the business application is to be registered using either a user name / password combination or a user token. |
Delete Service URL |
The URL used to delete tokens from the Oracle Access Management server. |
Mobile Authentication Scheme |
Specifies the authentication scheme to use to authenticate the user. The values for this should be from the enum |
Offline Authentication Retry Count |
The maximum number of times that offline authentication should be tried before sending a failure back to the client. |
Participation in SSO |
Specifies if the application supports Mobile Single Sign-on. |
Profile Cache Duration |
The length of time in minutes that the system should cache the application profile. |
Registration Service URL |
The registration service URL used to register the device. |
Relying Party Authentication Mode |
Specifies if Internet Identity Authentication should be invoked from inside an embedded webview or from an external browser. Valid values are Embedded or External. |
Relying Party Authentication URL |
The relying party authentication URL. |
Token Validation Service URL |
The service URL used to validate tokens. |
URL Scheme |
Specifies the URL scheme to use for the Internet Identity return URL, for example: rp:// |
User Authentication Service URL |
The service URL used to authenticate a user against Oracle Access Manager server. |
User Profile Service URL |
The service URL used to access the user and group information from the configured directory server. |
Configure the following attributes in the Mobile and Social administration console under the Custom Settings section of the application profile. For the attribute to be configured, enter the attribute "Name" in the console as it is given in the following table. The attribute values will be downloaded as part of the application profile and the SDK will populate the values internally.
Table 10-2 Attributes Configured in the Console UI
Attribute | Description |
---|---|
|
The length of time in seconds after which the HTTP connection between the server and the SDK times out. |
|
An enum of CryptoScheme that represents how the password will be hashed or encrypted to store for offline authentication. Valid values are |
|
The length of time in seconds after which the offline authentication context is deleted. |
Step 2: Complete the Authentication Process
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(OMAuthenticationContext context, OMMobileSecurityException mse)
. All the details with respect to the authenticated session are available in the OMAuthenticationContex
t 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(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.
As an alternative to the constructor specified in Section 10.2, you can use the following constructor to initialize the Android Client SDK.
public OMMobileSecurityService(Context context, Map<String, Object> configProperties,OMMobileServiceCallback callback)
This constructor accepts details at the start and initializes the OMMobileSecurityService
object using Map<String, Object>
. This enables you to specify additional parameters such as OM_PROP_AUTH_KEY
, OM_PROP_LOCATION_UPDATE_ENABLED
, and OM_PROP_CRYPTO_SCHEME
that cannot be specified during initialization using the constructor described previously. These properties are documented in Table 10-3. The same parameters can also be set using setters if you prefer to construct the OMMobileSecurityService
object using the constructor described in Section 10.2. The following is an example:
OMMobileSecurityConfiguration mobileSecurityConfiguration = mobileSecurityService.getMobileSecurityConfig(); MobileSecurityConfiguration.setLocationUpdateEnabled(true);
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, "xyzDomain"); configProp.put(OMMobileSecurityService.OM_PROP_APPNAME, "ShopCart"); configProp.put(OMMobileSecurityService.OM_PROP_OAMMS_URL, "http://examplehost.us.example.com:14100"); //This next line is optional. If you do not include it, a default key //is used which is <OAMMS_URL>_<APPNAME>_<SERVICE_DOMAIN> //configProp.put(OMMobileSecurityService.OM_PROP_AUTH_KEY, "testKey"); OMMobileSecurityService mss = new OMMobileSecurityService(getApplicationContext(), configProp, callback); //In the previous line, getApplicationContext() is the context of the //calling application, and callback is the instance of a class that has //implemented the interface OMMobileServiceCallback.
The following table documents the keys you use to put values in Map<String, Object>
.
Table 10-3 Android Client SDK Initialization Properties
Property Name | Property Value(s) | Type |
---|---|---|
|
|
Enum |
|
Required property. A String that contains the protocol, host, and port information as follows: <protocol> |
String |
|
Required property. Any valid Service Domain name passed as a String object. |
String |
|
Required property. A valid application name passed as a String object. |
String |
|
The key that must be used to store the 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 |
|
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 |
|
Specifies how authentication should happen, specifically whether authentication should be always done online/offline, or if it should happen online/offline depending on network connectivity. This is an optional property. By default, authentication will happen online/offline depending on network connectivity. |
Enum(OMConnectivityMode) |
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.11, "Using the Cryptography APIs."
Table 10-4 Cryptography Scheme Property Attributes for the Android Client SDK
Property Name | Property enum Values | Attribute Name | Attribute Value |
---|---|---|---|
|
|
CryptoScheme |
PlainText |
|
AES |
||
|
SHA-1 |
||
|
SHA-224 |
||
|
SHA-256 |
||
|
SHA-384 |
||
|
SHA-512 |
||
|
SaltedSHA-1 |
||
|
SaltedSHA-224 |
||
|
SaltedSHA-256 |
||
|
SaltedSHA-384 |
||
|
SaltedSHA-512 |
Mobile and Social supports offline authentication.
Specify the way that offline authentication should happen when creating the OMMobileSecurityService
object. Use the OM_PROP_CONNECTIVITY_MODE
key as documented in Table 10-3. This key accepts the following values:
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.
You can also set offline authentication after creating the OMMobileSecurityService
object using the corresponding setter as shown below:
OMMobileSecurityConfiguration mobileSecurityConfiguration = mobileSecurityService.getMobileSecurityConfig(); mobileSecurityConfiguration.setConnectivityMode(OMConnectivityMode.OFFLINE);
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.
This section provides sample code that shows how to do Relying Party Authentication with the Mobile and Social Server. Refer to the "Configuring Internet Identity Services" 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 username, 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 Internet 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()); } } ... }
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 "Introducing 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.9, "Creating a Custom Mobile Single Sign-on Agent App 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.
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()); } } … … }
Web apps can also use the single sign-on authentication features provided by the mobile SSO agent. This functionality requires Access Manager.
Log on to the Oracle Access Management Administration Console and click the Policy Configuration tab.
Under Shared Components click Authentication Schemes, then click the Create button.
The "Create Authentication Scheme" tab opens.
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
In the Oracle Access Management Administration Console, do the following:
Create a new Authentication Scheme in an Application Domain:
Authentication Scheme: MobileSSOScheme
(MobileSSOScheme is the scheme that was created in step one.)
Create an HTTP Resource, for example /protectedRes
, and protect the resource using the created Authentication Scheme (MobileSSOScheme). This is the URI 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.
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.
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);
Obtain either an instance of UserManager
or RoleManger
as shown.
OMUserManager userManager = userProfileService.getUserManager(); OMRoleManager roleManager = userProfileService.getRoleManager();
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
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 so that any Access Manager protected app can use the embedded Web browser. Access Manager protected REST Web services, however, cannot be accessed using the Web browser.
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 value configured for // "OAMAuthUserAgentPrefix" parameter in OAM 11g R2 Webgate in user defined parameters 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
property. The same OAMAuthUserAgentPrefix
property value 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:
OMMobileSecurityService#processHttpRequest(HttpRequest)
invokes the URL provided by the mobile application.
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>"
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.
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.
If the request is valid, Mobile and Social returns an Access Token in the response.
The Mobile and Social SDK injects the token returned by the Mobile and Social server and accesses the protected URL.
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.
If the OMMobileSecurityService
object for the agent application is not initialized using the constructor OMMobileSecurityService(Context context, Intent intent, OMMobileServiceCallback callback)
, provide the OMCredentialStore object with the details shown in the following code snippet:
OMCredentialStore credentialService = mMobileSecurityService.getCredentialStoreService(); OMMobileSecurityConfiguration cnfg = mMobileSecurityService.getMobileSecurityConfig(); credentialService.putString("sdkInitParams_serverUrl", cnfg.getServerURL().toString()); credentialService.putString("sdkInitParams_serviceDomain", cnfg.getServiceDomain()); credentialService.putString("sdkInitParams_applicationId",appID); //appID is the application ID string
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 || 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 */ } }
The agent can have self-authentication logic in the app as shown here:
@Override public void onClick(View v) { switch (v.getId()) { case R.id.login_button: try { if (!((SSOApplication) getApplication()).isSetupCompleted()) { mMobileSecurityService.setup(); } authView = mMobileSecurityService.authenticate(); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT); relLayout.addView(authView,params); } catch (OMMobileSecurityException e) { e.printStackTrace(); } break; … … } }
The SDK displays a basic log in view and knowledge-based answer view by default. To create custom user-defined layouts do the following:
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
.
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 username 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); } } }
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 OMMobileSecurityService#getCryptoService()
as follows:
OMCryptoService cryptoService = mMobileSecurityService.getCryptoService();
Following is a high-level summary of the functionality provided by the cryptography API.
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);
This API helps perform symmetric key encryption and decryption of data. The key used for encryption is generated automatically and stored in the credential store.
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);
The key for decryption is automatically retrieved from the credential store and the decrypted text is given as output by the following method. The key is generated automatically by the SDK when the encrypt
method is called for the first time.
cryptoService.decrypt(encodedText);
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.
cryptoService.match(password, passwordStored, mss.getMobileSecurityConfig().getSaltLength());
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:
mMobileSecurityService
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
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-5 Mobile and Social Android Client SDK Error Codes and Messages
Error Code | Description |
---|---|
|
This exception is thrown when the SDK cannot connect to the server. This may occur because of a URISyntaxException, an IllegalArgumentException, and so on. |
|
This exception is thrown when the user does not provide a challenge answer in the case of knowledge-based authentication (KBA). |
|
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. |
|
This exception is thrown if the required tokens that you requested are not present in the tokens returned by the server. |
|
This exception is thrown when the |
|
This exception is thrown when the authentication with |
|
This exception is thrown if the untrusted SSL certificate is rejected by the user. |
|
This exception is thrown when there is no authentication scheme provided in the mobile security configuration object. |
|
This exception is thrown if the supplied authentication URL is not valid. |
|
This exception is thrown when the user authentication fails due to some internal errors from the server. |
|
This exception is thrown if authentication is not successful due to an incorrect identity domain, username, or password. |
|
This exception is thrown when the SDK is not able to construct a valid RP login 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. |
|
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. |
|
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. |
|
This exception is thrown if the |
|
This exception is thrown when the |
|
This exception is thrown when the service domain of the SSO application does not match the service domain of the SSO client application. |
|
This exception is thrown when the user is trying to execute |
|
This exception is thrown when the SSO application is not able to validate the application signature of the calling business application. |
|
This exception is thrown when any application is initialized through the URL scheme and the appropriate fields are not supplied. |
|
This exception is thrown for all other exceptions raised from the SDK. |