Migrating Authentication and Security Concepts

improve this page | report issue

Overview

The IBM Mobile Foundation security framework was significantly modified in V8.0 to improve and simplify security development and administration tasks. These changes include the replacement of the V7.1 security building blocks: in V8.0, OAuth security scopes and security checks replace the security tests, realms, and login modules of previous versions.

This tutorial guides you through the required steps for migrating the security code of your application to V8.0. The tutorial outlines the complete process for transforming a sample MobileFirst V7.1 application into a V8.0 application with the same security protection. Both the sample V7.1 application and the migrated V8.0 application are available for download. See the Download migration sample link at the start of this tutorial.

The first part of the tutorial explains how to migrate the sample V7.1 application to V8.0. This includes migrating the resource adapter, replacing the form-based and adapter-based authentication realms with security checks, and migrating the client application and its challenge handlers.
The second part explains how to migrate to V8.0 other types of V7.1 authentication realms, which are not demonstrated in the sample application.
The third part explains how to migrate to V8.0 additional V7.1 security configurations. This includes configuration of application-level protection, access-token expiration, and user and device identities.

Note: Before you start the migration, you are advised to read the V8.0 migration cookbook.
To learn about the basic concepts of the new security framework, see Authentication and Security.

Migration of authentication realms using the migration assistance tool

Migration of the supported realms into security checks is made easier with migration assistance tool. See here, for more information.

Migrating the sample application

The starting point for this migration procedure is a sample V7.1 hybrid application. The application accesses a Java adapter that is protected with the V7.1 OAuth security model. The adapter has two methods:

  • getBalance, which is protected with a form-based authentication realm that implements a user-name and password login.
  • transferMoney, which is protected with an adapter-based authentication realm that implements a pin-code based user authorization.

Use the Download migration sample link at the start of this tutorial to download the source code of the V7.1 sample application and of its migrated V8.0 equivalent.

Follow these steps to migrate the sample V7.1 application to V8.0:

Migrating the resource adapter

Start by migrating the resource adapter. In Mobile Foundation V8.0, adapters are developed as separate Maven projects, unlike in V7.1 where adapters are part of the application project. Thus, you can migrate the resource adapter, and build and deploy the migrated adapter, independently of the client application. The same is true for the V8.0 client application, and the V8.0 security checks (which are implemented within adapters). Therefore, you can migrate these artifacts in the order of your choice. The tutorial begins with instructions for migrating the resource adapter, including an introduction the OAuth security scope elements that are used for the V8.0 resource protection.

Note:

  • The following instructions are for the migration of the sample AccountAdapter resource adapter. You do not need to migrate the sample PinCodeAdapter because the adapter-based authentication that it implements is no longer supported in V8.0. The Replacing the pin-code adapter-based authentication realm step explains how to replace the V7.1 pin-code adapter with a V8.0 security check that offers similar protection.
  • For instructions on how to migrate adapters to V8.0, see the V8.0 migration cookbook.

The AccountAdpter methods in the V7.1 sample are protected with the @OAuthSecurity annotation, which defines the methods’ protecting scopes (UserLoginRealm and PinCodeRealm). The same annotation is used in V8.0, but the scope elements have a different significance: in V7.1, scope elements refer to security realms that are defined in the authenticationConfig.xml file. In V8.0, scope elements are mapped to security checks that are defined in an adapter that is deployed to MobileFirst Server. You can select to keep the resource-protection code, including the scope-element names, unchanged. However, because the “realm” terminology is no longer used in Mobile Foundation V8.0, the scope elements in the V8.0 application are renamed to UserLogin and PinCode:

@OAuthSecurity(scope="UserLogin")
@OAuthSecurity(scope="PinCode")

Updating the user-identity retrieval code

The sample resource adapter uses the server-side security API to obtain the identity of the authenticated user. This API changed in V8.0, so you need to modify the adapter code to use the updated API. In the migrated V8.0 application, remove the following V7.1 code:

WLServerAPI api = WLServerAPIProvider.getWLServerAPI();
api.getSecurityAPI().getSecurityContext().getUserIdentity();

And replace it with the following code, which uses the new V8.0 API:

// Inject the security context
@Context
AdapterSecurityContext securityContext;

 // Get the authenticated user name
String userName = securityContext.getAuthenticatedUser().getDisplayName();

After you edit the adapter code, build the adapter and deploy it to the server by using either Maven or the MobileFirst CLI. For more information, see Build and Deploy Adapters.

Migrating the client application

Next, migrate the client application. For detailed client-application migration instructions, see the V8.0 migration cookbook. This tutorial focuses on the migration of the security code. At this stage, exclude the challenge-handler code by editing the application’s main HTML file, index.html, to add a comment around the lines that import the challenge-handler code:

<!--  
    <script src="js/UserLoginChallengeHandler.js"></script>
    <script src="js/PinCodeChallengeHandler.js"></script>
 -->

The sample application’s challenge-handler code is modified later, in the Migrating the challenge handlers step.

Updating the client-side API calls

As part of the client migration, you need to adapt to V8.0 client-side API changes. For a list of Mobile Foundation V8.0 client-API changes, see Upgrading the WebView. The sample application has one client-API change that is related to security, the logout API. The V7.1 WL.Client.logout method is not supported in V8.0. Instead, use the V8.0 WLAuthorizationManager.logout method, and pass to it the name of the security check that replaces the V7.1 authorization realm. The Logout button in the sample application logs the user out of both the UserLogin and PinCode security checks:

function logout() {
    WLAuthorizationManager.logout('UserLogin').then(
        function () {
            WLAuthorizationManager.logout('PinCode').then(function () {
                $("#ResponseDiv").html("Logged out");
            }, function (error) {
                WL.Logger.debug("failure on logout from PinCode check: " +
                    JSON.stringify(error));
            });
      },
      function (error) {
          WL.Logger.debug("failure on logout from UserLogin check: " +
              JSON.stringify(error));
      });
}

When you complete the client-application migration steps, build the application, and then register it to your MobileFirst Server with the command mfpdev app register. After you successfully register your application, you can see it listed in the Applications section of the MobileFirst Operations Console navigation sidebar.

Migrating the sample application’s authentication realms

At this stage, you already have a migrated V8.0 client application and a deployed resource adapter. However, your migrated application cannot access the protected adapter resources. The reason is that the resource-adapter methods are protected by UserLogin and PinCode scope elements that are not yet mapped to any security checks. Therefore, the application cannot acquire the required access token for accessing the protected methods. To resolve this, you need to replace the V7.1 authentication realms with V8.0 security checks that map to the adapter methods’ protecting scope elements.

Replacing the user-login form-based authentication realm

To replace the V7.1 UserLoginRealm form-based authentication realm, create a V8.0 UserLogin security check, which performs the same authentication steps as the V7.1 form-based authenticator and custom login module: the security check should send a challenge to the client, collect the login credentials from the challenge response, validate the credentials, and create a user identity. As demonstrated in the following instructions, creating the security check is not complicated. After you create the security check, you can copy the code for validating the login credentials from the V7.1 custom login module to the new security check.

In V8.0, security checks are implemented as adapters. In Mobile Foundation V8.0, a Java adapter can both serve resources and package security tests. However, in this migration procedure you maintain the migrated AccountAdpter resource adapter, and you create a separate adapter for packaging your new security check. Therefore, start by creating a new Java adapter named UserLogin. For detailed instructions, see creating a new Java adapter.

To define a UserLogin security check in your new UserLogin adapter, add a <securityCheckDefinition> XML element to the adapter’s adapter.xml file, as demonstrated in the following code:

<securityCheckDefinition name="UserLogin" class="com.sample.UserLogin">
     <property name="successStateExpirationSec" defaultValue="3600"/>
</securityCheckDefinition>
  • The name attribute specifies the name of your security check (“UserLogin”).
  • The class attribute specifies the Java class of the security-check implementation (“com.sample.UserLogin”). This class is created in the next step.
  • The successStateExpirationSec property is equivalent to the expirationInSeconds property of the V7.1 login modules. It indicates the expiration period for the security-check’s successful state (meaning, the interval, in seconds, during which a successful security-check login remains valid). The default value of both of these V7.1 and V8.0 properties is 3600 seconds. If you configured a different expiration period in your V7.1 login module, edit the value of the V8.0 successStateExpirationSec property to set the same value.

This tutorial explains how to define only the successStateExpirationSec property, but you can do much more with security checks. For example, you can implement advanced features such as blocked state expiration, multiple login attempts, or a “remember me” login. You can change the default values of configuration properties, add custom properties, and modify property values at run time from the MobileFirst Operations Console or by using the MobileFirst CLI (mfpdev). For more information, see the V8.0 security-checks documentation, and in particular Configuring security checks.

Creating the user-login security-check Java class

In your UserLogin adapter, create a UserLogin Java class that extends the MobileFirst UserAuthenticationSecurityCheck abstract base class (which in turn extends the MobileFirst CredentialsValidationSecurityCheck abstract base class). Next, override the default implementations of the createChallenge, validateCredentials, and createUser base-class methods.

  • The createChallenge method creates the challenge object (hash map) to be sent to the client. The implementation of this method can be modified to include a challenge phrase or another type of challenge object to be used for validating the client’s response. However, for the purposes of the sample application, you only need to add to the challenge object the error message to display if an error occurs.
  • The validateCredentials method contains the authentication logic. Copy the authentication code that validates the user name and password from your V7.1 login module to this V8.0 method. The sample implements a basic validation logic, which verifies that the password is identical to the user name.
  • The createUser method is the equivalent of the createIdentity method of the V7.1 login module.

Following is the complete class-implementation code:

public class UserLogin extends UserAuthenticationSecurityCheck {
    private String userId, displayName;
    private String errorMsg;

    @Override
    protected boolean validateCredentials(Map<String, Object> credentials) {
        if (credentials!=null && credentials.containsKey("username") &&
		credentials.containsKey("password")){
            String username = credentials.get("username").toString();
            String password = credentials.get("password").toString();

            // the authentication logic, copied from the V7.1 login module
            if (!username.isEmpty() && !password.isEmpty() && username.equals(password)) {
                userId = username;
                displayName = username;

                errorMsg = null;
                return true;
            } else {
                errorMsg = "Wrong Credentials";
            }
        } else {
            errorMsg = "Credentials not set properly";
        }
        return false;
    }

    @Override
    protected Map<String, Object> createChallenge() {
        Map challenge = new HashMap();
        challenge.put("errorMsg", errorMsg);
        return challenge;
    }

    @Override
    protected AuthenticatedUser createUser() {
        return new AuthenticatedUser(userId, displayName, this.getName());
    }
}

For more information about the UserAuthenticationSecurityCheck class and its implementation, see Implementing the UserAuthenticationSecurityCheck Class.

To complete your changes, build the UserLogin adapter and deploy it to the server by using either Maven or the MobileFirst CLI. For more information, see Build and Deploy Adapters. After you successfully deploy the adapter, you can see it listed in the Adapters section of the MobileFirst Operations Console navigation sidebar.

Replacing the pin-code adapter-based authentication realm

The V7.1 sample application’s PinCodeRealm realm is implemented with adapter-based authentication, which is no longer supported in V8.0. In place of this realm, create a new PinCode Java adapter, and add to it a PinCode Java class that extends the MobileFirst CredentialsValidationSecurityCheck abstract base class.

Note:

  • The steps for creating the PinCode adapter are similar to the steps for creating the UserLogin adapter, as outlined in the Replacing the user-login form-based authentication realm step.
  • The PinCode security check only needs to validate the login credentials (the pin code), and does not need to assign a user identity. Therefore, this security-check class extends the CredentialsValidationSecurityCheck base class and not the UserAuthenticationSecurityCheck class that is used for the UserLogin security check.

To create a security check that extends the CredentialsValidationSecurityCheck base class, you need to implement the createChallenge and validateCredentials methods.

  • The createChallenge implementation is similar to that of the UserLogin security check. The PinCode security check does not have any special information to send to the client as part of the challenge. Therefore, you only need to add to the challenge object the error message to display if an error occurs.

        @Override
        protected Map<String, Object> createChallenge() {
            Map challenge = new HashMap();
            challenge.put("errorMsg",errorMsg);
            return challenge;
        }
    
  • The validateCredentials method validates the pin code. In the following example, the validation code consists of a single line, but you can also copy the validation code from the V7.1 authentication adapter into this validateCredentials method.

    @Override
    protected boolean validateCredentials(Map<String, Object> credentials) {
        if (credentials!=null && credentials.containsKey("pin")){
            String pinCode = credentials.get("pin").toString();
            if (pinCode.equals("1234")) {
                return true;
            } else {
                errorMsg = "Pin code is not valid.";
            }
        } else {
            errorMsg = "Pin code was not provided";
        }
        return false;
    }
    

When you complete the migration of the V7.1 authentication realms to security checks, build the adapter and deploy it to MobileFirst Server. For more information, see Build and Deploy Adapters.

Migrating the challenge handlers

At this stage, you already migrated the sample resource adapter and client application, and replaced the V7.1 authentication realms with V8.0 security checks. All that remains to complete the security migration of the sample application is to migrate the client-application’s challenge handlers. The client application uses the challenge handlers to respond to security challenges and send the credentials that are received from the user to the security checks.

When you migrated the client application, you excluded the challenge-handler code by commenting out the relevant lines in the application’s main HTML file, index.html. Now, add back the application’s challenge-handler code, by removing the comment that you previously added around these lines:

    <script src="js/UserLoginChallengeHandler.js"></script>
    <script src="js/PinCodeChallengeHandler.js"></script>

Then, proceed to migrate the challenge-handler code to V8.0, as outlined in the following instructions. For more information about the V8.0 challenge-handler API, see Quick Review of Challenge Handlers in Mobile Foundation 8.0 and the WL.Client and WL.Client.AbstractChallengeHandler documentation in the V8.0 JavaScript Client-side API Reference.

Start with the user-login challenge handler (userLoginChallengeHandler), which performs the same functions in V8.0 as it does in V7.1: this challenge handler is responsible for presenting the login form to the user upon arrival of a challenge, and for sending the user name and password to MobileFirst Server. However, because the client challenge-handler API in V8.0 is different and simpler than its V7.1 counterpart, you need to make the following changes:

  • Replace the code for creating the challenge handler with the following code, which calls the V8.0 WL.Client.createSecurityCheckChallengeHandler method:

    var userLoginChallengeHandler = WL.Client.createSecurityCheckChallengeHandler('UserLogin');
    

    WL.Client.createSecurityCheckChallengeHandler creates a challenge handler that handles challenges from a MobileFirst security check. V8.0 also introduces a WL.Client.createGatewayChallengeHandler method for handling challenges from a third-party gateway, which are known in V8.0 as gateway challenge handlers. When you migrate a V7.1 application to V8.0, replace calls to the WL.Client createWLChallengeHandler or createChallengeHandler method with calls to the V8.0 WL.Client challenge-handler creation method that matches the expected challenge source. For example, if your resource is protected by a DataPower reverse proxy that sends a custom login form to the client, use createGatewayChallengeHandler to create a gateway challenge handler to handle the gateway challenges.

  • Remove the call to the challenge-handler isCustomResponse method. In V8.0, this method is no longer needed to handle security challenges.
  • Replace the implementation of the userLoginChallengeHandler.handleChallenge method with implementations of the V8.0 challenge-handler handleChallenge, handleSuccess, and handleFailure methods. V7.1 has a single challenge-handler method that checks the response to determine whether it contains a challenge or returns success or an error. V8.0 has a separate method for each type of challenge-handler response, and the security framework determines the response type and calls the appropriate method.
  • Remove the call to the submitSuccess method. The V8.0 security framework handles the success response implicitly.
  • Replace the call to the submitFailure method with a call to the V8.0 cancel challenge-handler method.
  • Replace the call to the submitLoginForm method with a call to the V8.0 submitChallengeAnswer challenge-handler method:

    userLoginChallengeHandler.submitChallengeAnswer({'username':username, 'password':password})
    

The complete code of the challenge handler after you apply these changes is shown here:

function createUserLoginChallengeHandler() {
    var userLoginChallengeHandler = WL.Client.createSecurityCheckChallengeHandler('UserLogin');

    userLoginChallengeHandler.handleChallenge = function(challenge) {
        showLoginDiv();
        var statusMsg = (challenge.errorMsg !== null) ? challenge.errorMsg : "";
        $("#loginErrorMessage").html(statusMsg);
    };

    userLoginChallengeHandler.handleSuccess = function(data) {
        hideLoginDiv();
    };

    userLoginChallengeHandler.handleFailure = function(error) {
        if (error.failure !== null) {
            alert(error.failure);
        } else {
            alert("Failed to login.");
        }
    };

    $('#AuthSubmitButton').bind('click', function () {
        var username = $('#AuthUsername').val();
        var password = $('#AuthPassword').val();
        if (username === "" || password === "") {
            alert("Username and password are required");
            return;
        }

        userLoginChallengeHandler.submitChallengeAnswer(
            {'username':username, 'password':password});});

    $('#AuthCancelButton').bind('click', function () {
        userLoginChallengeHandler.cancel();
        hideLoginDiv();
    });

    return userLoginChallengeHandler;
}

The migration of the pin-code challenge handler (pinCodeChallengeHandler) is similar to the migration of the user-login challenge handler. Therefore, follow the userLoginChallengeHandler migration instructions, and make the necessary adjustments for the pin-code challenge handler. See the full code of the migrated pin-code challenge handler in the sample V8.0 application.

You are now done with the migration of the sample V7.0 application to V8.0. Rebuild the application, deploy it to MobileFirst Server, test it, and verify that access to the adapter-method resources is protected as expected.

Migrating other types of authentication realms

So far, you learned how to migrate the form-base and adapter-based realms, which are part of the sample V7.1 application. However, your V7.1 application might include other types of authentication realms, including realms that are part of the application security test (mobileSecurityTest, webSecurityTest, or customSecurityTest). The following sections outline how to migrate these additional types of authentication realms to V8.0.

Application authenticity

In Mobile Foundation V8.0, application-authenticity validation is provided as a predefined security check, appAuthenticity. By default, this security check is run during the application’s runtime registration with MobileFirst Server, which occurs the first time an instance of the application attempts to connect to the server. However, as with any MobileFirst security check, you can also include this predefined check in custom security scopes. For more information, see Application Authenticity.

LTPA realm

To replace the V7.1 LTPA realm, use the Mobile Foundation V8.0 predefined LTPA-based SSO security check, LtpaBasedSSO. For more information about this security check, see LTPA-based single sign-on (SSO) security check.

Device provisioning

The V7.1 device-provisioning realm (wl_deviceAutoProvisioningRealm) does not require migration to V8.0. The Mobile Foundation V8.0 client-registration process replaces the V7.1 device provisioning. In V8.0, a client (an instance of an application) registers itself with MobileFirst Server on the first attempt to access the server. As part of the registration, the client provides a public key that will be used to authenticate its identity. This protection mechanism is always enabled, therefore there is no need for a security check to replace the V7.1 device-provisioning realm.

Anti-cross site request forgery (anti-XSRF) realm

The V7.1 anti-cross site request forgery (anti-XSRF) realm (wl_antiXSRFRealm) does not require migration to V8.0. In V7.1.0, the authentication context is stored in the HTTP session and identified by a session cookie, which is sent by the browser in cross-site requests. The anti-XSRF realm in this version is used to protect the cookie transmission against XSRF attacks by using an additional header that is sent from the client to the server. In Mobile Foundation V8.0, the security context is no longer associated with an HTTP session and is not identified by a session cookie. Instead, the authorization is done by using an OAuth 2.0 access token that is passed in the Authorization header. Because the Authorization header is not sent by the browser in cross-site requests, there is no need to protect against XSRF attacks.

Direct Update realm

The V7.1 remote-disable realm (wl_directUpdateRealm) does not require migration to V8.0. The Mobile Foundation V8.0 implementation of the Direct Update feature does not require a related security check, unlike the realm requirement in V7.1.

Note: The V8.0 steps for delivering updates with Direct Update are different from the V7.1 procedure. For more information, see Migrating Direct Update.

Remote-disable realm

The V7.1 remote-disable realm (wl_remoteDisableRealm) does not require migration to V8.0. The Mobile Foundation V8.0 implementation of the remote-disable feature does not require a related security check, unlike the realm requirement in V7.1. For information about the remote-disable feature in V8.0, see Remotely disabling application access to protected resources.

Custom authenticators and login modules

To replace the custom V7.1 authenticators and login modules, create a new security check, according to instructions in the Creating the user-login security-check Java class sample-application migration step. Your security check can extend either the UserAuthenticationSecurityCheck or CredentialsValidationSecurityCheck Mobile Foundation V8.0 base class. Although you cannot migrate the V7.1 authenticator class or the login module class directly, you can copy relevant code pieces into your security check. This includes code for generating the security challenge, extracting login credentials from the challenge response, or validating the credentials.

Migrating other V7.1 security configurations

The application security test

In V7.1, the application descriptor (application-descriptor.xml) can define an application security test that is applied to the entire application environment, in addition to the protection that is applied to specific application resources. The default V7.1 mobile-application security test, which is applied when the application descriptor does not explicitly define a security test (such as in the sample V7.1 application), is mobileSecurityTest. This security test consists of realms that are either not relevant in V8.0 (anti-XSRF) or do not require explicit migration (Direct Update and remote disable). Therefore, no specific migration is required for the sample application’s application-environment protection.

If your V7.1 application has an application security test with checks (realms) that you want to keep at the application level after the migration to V8.0, you can configure a mandatory application scope. In V8.0, access to a protected resource requires passing both the security checks that are mapped to the mandatory application scope and the checks that are mapped to the resource’s protecting scope. To define a mandatory application scope, in the V8.0 MobileFirst Operations Console, select your application from the Applications section of the navigation sidebar, and then select the Security tab. Under Mandatory Application Scope, select Add to Scope. You can include in the application scope any predefined or custom security checks, or mapped scope elements. For more information about configuration of a mandatory application scope in V8.0, see Mandatory application scope.

Access-token expiration

The default value of the maximum access-token expiation period in both V7.1 and V8.0 is 3600 seconds. Therefore, if your V7.1 application relies on this default value, no migration work is required to apply the value also in V8.0. However, if your V7.1 application-descriptor file (application-descriptor.xml) sets a different value for the accessTokenExpiration property, you can configure the same value for the equivalent V8.0 property (maxTokenExpiration). You can do this from the MobileFirst Operations Console by going to your application’s Security tab, and editing the default value of the Maximum Token-Expiration Period (seconds) field in the Token Configuration section. If you select the application’s Configuration Files console tab, you can see that the value of the maxTokenExpiration property is set to your configured value.

User-identity realm

In V7.1, authentication realms can be configured as user-identity realms. Applications that use the authentication flow of the MobileFirst OAuth security model, use the userIdentityRealms property in the application-descriptor file to define an ordered list of user-identity realms. In applications that use the authentication flow of the MobileFirst classic (non-OAuth) security model, the attribute isInternalUserId signifies whether the realm is a user-identity realm. In V8.0, these user-identity configurations are no longer needed. In V8.0, the identity of the active user is set by the last security check that called the setActiveUser method. If your security check extends the abstract UserAuthenticationSecurityCheck base class, such as the sample V8.0 UserLogin check, you can rely on the base class to set the identity of the active user.

Device-identity realm

A V7.1 application must define a device-identity realm. In V8.0, this realm is no longer required. In V8.0, the device identity is not associated with a security check. Instead, the device information is registered as part of the client registration flow, which occurs the first time that the client attempts to access a protected resource.

What’s next

This tutorial covers only the basic steps that are required for migrating to V8.0 the security artifacts of an existing application, developed with a previous version of Mobile Foundation. To take full advantage of the V8.0 security features, see the V8.0 security-framework documentation.

Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.
Last modified on June 01, 2020