Device enrollment consists of registering a specific device as a trusted device from a customer’s perspective. From an enrolled device, a customer might want to see some basic information without needing to log in, more secure information would require a PIN code, while changes to the account might require full credentials.
Prerequisite: This advanced tutorial requires good understanding of IBM MobileFirst Platform Foundation security concepts such as security tests, realms, challenge handlers, etc. Review the tutorials and IBM knowledge center if you are not comfortable with those concepts.
In this example, here is the application flow:
When the application is opened, it sends a request to the server to check if this device is currently enrolled.
If the device is not recognized, the enrollment process is started.
To enroll, the user first needs to log in with standard credentials.
After the user is authenticated, he is asked to set a PIN code for quick access to sensitive information.
After successful enrollment, the user has access to the bank account balance.
Closing the application and re-opening it again shows the balance page immediately without login.
For access to a button to see detailed transactions, the user must enter the defined PIN code each time.
By using a Logout button, the user can start everything from the beginning.
Username/Password Security Test
For a username/password security test, a simple adapter-based realm is used.
This simple NonValidatingLoginModule lets the adapter-based authenticator handle the validation.
By using AdapterAuthenticator, you can write the login logic in an adapter. The login-function is used to trigger a challenge.
UsernamePasswordRealm is used as the internal user ID, while the built-in wl_deviceNoProvisioningRealm helps get the device ID automatically from the device. The direct update and anti-XSRF realms are additional internal realms that are not specific to this scenario.
This procedure notifies the client that the given resource requires username/password authentication. You must implement a challenge handler to react to this flag.
This procedure checks the validity of the user name and password, while setting the current user in the session when successful. In this example, a “correct” username/password combination is any 2 strings that are exactly the same. In the real world, of course, the combination is verified by a database or a back-end service.
The challenge handler needs to be registered. Checking for usernamePasswordRequired in the response allows to determine whether the challenge needs to be handled.
If the challenge needs to be handled, simply show an HTML login form (and show errors if any). The submit button of this form is linked to the login() function below.
The login function uses the submitAdapterAuthentication API (which is the same as the invokeProcedure API) to send the entered user name and password for verification against the adapter. Upon success, use submitSuccess to let the application continue its flow.
Enrolled devices need to be saved in a database of trusted devices that are associated with their user account.
This non-validating login module leaves the responsibility of validating the data to you.
Again, an AdapterAuthenticator is used to check the enrollment.
In the adapter, this procedure is defined to let the client know that a given resource requires enrollment.
Similar to the previous security test, this security test uses some predefined realms in addition to our EnrollmentRealm.
In your application, you might want to use an external database or a back-end service to safely store the list of enrolled devices. This sample includes a Java class that emulates storage of JSON objects for a given ID string. The implementation of this class is not important and its public API features 3 methods: getInfo(id), setInfo(id, info), removeInfo(id), where “info” is an arbitrary JSON object.
In the adapter code, a reference to this class is declared:
For a device to be enrolled, the currently used device ID and the currently logged-in user need to be retrieved. Together with a PIN code provided by the user, this information is saved in the enrolled devices storage.
Because only logged-in users can enroll, this procedure is protected by the username/password realm.
This adapter procedure retrieves the current device ID and checks it against the enrolled list. If the device is enrolled, the user is logged in to the enrollment realm.
To make testing easier, a procedure is added so that you can remove the current device from the devices list and log out from all realms.
Pre-emptive login and enrollment
While you could wait for a challenge, you can also write client logic to pre-emptively trigger a login or enrollment.
In this sample, when the application starts, the following method is called.
This code checks whether the device is already enrolled. If it is, the account balance is shown. If the device is not enrolled, the code triggers the username/password authentication. Upon success, it shows the actual enrollment form, which requires to set up a PIN code.
Submitting this form triggers the setPinCode() function, then allows the user to see the balance.
Because device enrollment is triggered pre-emptively by the client, the challenge handler for the EnrollmentRealm should not occur. To catch a rare case, a simple challenge handler could reload the application when it happens.
PIN Code Protection
Some resources can be protected with the PIN code. In this sample, the getTransactions procedure is protected by a PIN code.
Accessing a PIN-protected resource requires both the PinCodeRealm and the EnrollmentRealm realms.
When a resource is protected by a PinCodeRealm realm, the challenge handler is called. It shows a form that prompts the user to enter the valid PIN code. Clicking the button triggers the verifyPinCode function.
This function sends the PIN code attempt to the adapter for verification.
This procedure retrieves the enrollment information from the enrolled devices list and compares the set PIN code. A successful procedure means that the device was found in the list and that the PIN that was entered matches the stored one. When the procedure is successful, the state is saved in the session.