Authentication and Security

improve this page | report issue

Overview

The MobileFirst security framework is based on the OAuth 2.0 protocol. According to this protocol, a resource can be protected by a scope that defines the required permissions for accessing the resource. To access a protected resource, the client must provide a matching access token, which encapsulates the scope of the authorization that is granted to the client.

The OAuth protocol separates the roles of the authorization server and the resource server on which the resource is hosted.

  • The authorization server manages the client authorization and token generation.
  • The resource server uses the authorization server to validate the access token that is provided by the client, and ensure that it matches the protecting scope of the requested resource.

The security framework is built around an authorization server that implements the OAuth protocol, and exposes the OAuth endpoints with which the client interacts to obtain access tokens. The security framework provides the building blocks for implementing a custom authorization logic on top of the authorization server and the underlying OAuth protocol. By default, MobileFirst Server functions also as the authorization server. However, you can configure an IBM WebSphere DataPower appliance to act as the authorization server and interact with MobileFirst Server.

The client application can then use these tokens to access resources on a resource server, which can be either the MobileFirst Server itself or an external server. The resource server checks the validity of the token to make sure that the client can be granted access to the requested resource. The separation between resource server and authorization server allows you to enforce security on resources that are running outside MobileFirst Server.

Application developers protect access to their resources by defining the required scope for each protected resource, and implementing security checks and challenge handlers. The server-side security framework and the client-side API handle the OAuth message exchange and the interaction with the authorization server transparently, allowing developers to focus only on the authorization logic.

Jump to:

Authorization entities

Access Tokens

A MobileFirst access token is a digitally signed entity that describes the authorization permissions of a client. After the client’s authorization request for a specific scope is granted, and the client is authenticated, the authorization server’s token endpoint sends the client an HTTP response that contains the requested access token.

Structure

The MobileFirst access token contains the following information:

  • Client ID: a unique identifier of the client.
  • Scope: the scope for which the token was granted (see OAuth scopes). This scope does not include the mandatory application scope.
  • Token-expiration time: the time at which the token becomes invalid (expires), in seconds.

Token expiration

The granted access token remains valid until its expiration time elapses. The access token’s expiration time is set to the shortest expiration time from among the expiration times of all the security checks in the scope. But if the period until the shortest expiration time is longer than the application’s maximum token-expiration period, the token’s expiration time is set to the current time plus the maximum expiration period. The default maximum token-expiration period (validity duration) is 3,600 seconds (1 hour), but it can be configured by setting the value of the maxTokenExpiration property. See Configuring the maximum access-token expiration period.

Configure the application’s maximum access-token expiration period by using one of the following alternative methods:

  • Using the MobileFirst Operations Console
    • Select [your application] → Security tab.
    • In the Token Configuration section, set the value of the Maximum Token-Expiration Period (seconds) field to your preferred value, and click Save. You can repeat this procedure, at any time, to change the maximum token-expiration period, or select Restore Default Values to restore the default value.
  • Editing the application's configuration file
    1. From a command-line window, navigate to the project's root folder and run the mfpdev app pull.
    2. Open the configuration file, located in the [project-folder]\mobilefirst folder.
    3. Edit the file by defining a maxTokenExpiration property and set its value to the maximum access-token expiration period, in seconds:
      {
          ...
          "maxTokenExpiration": 7200
      }
    4. Deploy the updated configuration JSON file by running the command: mfpdev app push.

A successful HTTP response to an access-token request contains a JSON object with the access token and additional data. Following is an example of a valid-token response from the authorization server:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
    "token_type": "Bearer",
    "expires_in": 3600,
    "access_token": "yI6ICJodHRwOi8vc2VydmVyLmV4YW1",
    "scope": "scopeElement1 scopeElement2"
}

The token-response JSON object has these property objects:

  • token_type: the token type is always "Bearer", in accordance with the OAuth 2.0 Bearer Token Usage specification.
  • expires_in: the expiration time of the access token, in seconds.
  • access_token: the generated access token (actual access tokens are longer than shown in the example).
  • scope: the requested scope.

The expires_in and scope information is also contained within the token itself (access_token).

Note: The structure of a valid access-token response is relevant if you use the low-level WLAuthorizationManager class and manage the OAuth interaction between the client and the authorization and resource servers yourself, or if you use a confidential client. If you are using the high-level WLResourceRequest class, which encapsulates the OAuth flow for accessing protected resources, the security framework handles the processing of access-token responses for you. See Client security APIs and Confidential clients.

Refresh Tokens

A Refresh token is a special type of token, which can be used to obtain a new access token when the access token expires. To request a new access token, a valid refresh token can be presented. The refresh tokens are long-lived tokens and remain valid for a longer duration of time compared to access tokens.

Refresh token must be used with caution by an application because they can allow a user to remain authenticated forever. Social media applications, e-commerce applications, product catalog browsing and such utility applications, where the application provider does not authenticate users regularly can use refresh tokens. Applications that mandate user authentication frequently must avoid using refresh tokens.

MobileFirst Refresh Token

A MobileFirst refresh token is a digitally signed entity like access token that describes the authorization permissions of a client. Refresh token can be used to get new access token of the same scope. After the client’s authorization request for a specific scope is granted and the client is authenticated, the authorization server’s token endpoint sends the client an HTTP response that contains the requested access token and refresh token. When the access token expires, the client sends refresh token to authorization server’s token endpoint to get a new set of access token and refresh token.

Structure

Similar to the MobileFirst access token, the MobileFirst refresh token contains the following information:

  • Client ID: a unique identifier of the client.
  • Scope: the scope for which the token was granted (see OAuth scopes). This scope does not include the mandatory application scope.
  • Token-expiration time: the time at which the token becomes invalid (expires), in seconds.

Token Expiration

The token expiration period for refresh token is longer than the typical access token expiry period. The refresh token once granted remains valid until its expiration time elapses. Within this validity period, a client can use the refresh token to get a new set of access token and refresh token. The refresh token has a fixed expiry period of 30 days. Every time the client receives a new set of access token and refresh token successfully, the refresh token expiry is reset thus giving the client an experience of a never expiring token. The access token expiry rules remain same as explained in section Access Token.

Refresh token feature can be enabled using the following properties on client side and server side respectively.

Client side property (Android)
File name: mfpclient.properties
Property name: wlEnableRefreshToken
Property value: true
For example,
wlEnableRefreshToken=true

Client side property (iOS)
File name: mfpclient.plist
Property name: wlEnableRefreshToken
Property value: true
For example,
wlEnableRefreshToken=true

server-side property
File name: server.xml
Property name: mfp.security.refreshtoken.enabled.apps
Property value: application bundle id separated by ‘;’

For example,


            <jndiEntry jndiName="mfp/mfp.security.refreshtoken.enabled.apps" value='"com.sample.android.myapp1;com.sample.android.myapp2"'/>
            

Use different bundle ids for different platforms.


Following is an example of a valid refresh token response from the authorization server:

        HTTP/1.1 200 OK
        Content-Type: application/json
        Cache-Control: no-store
        Pragma: no-cache
        {
            "token_type": "Bearer",
            "expires_in": 3600,
            "access_token": "yI6ICJodHRwOi8vc2VydmVyLmV4YW1",
            "scope": "scopeElement1 scopeElement2",
            "refresh_token": "yI7ICasdsdJodHRwOi8vc2Vashnneh "
        }
        

The refresh-token response has the additional property object refresh_token apart from the other property objects explained as part of the access token response structure.


Note: The refresh tokens are long-lived compared to access tokens. Hence the refresh token feature must be used with caution. Applications where periodic user authentication is not necessary are ideal candidates for using the refresh token feature.

MobileFirst supports refresh token feature on iOS starting CD Update 3.

Security Checks

A security check is a server-side entity that implements the security logic for protecting server-side application resources. A simple example of a security check is a user-login security check that receives the credentials of a user, and verifies the credentials against a user registry. Another example is the predefined MobileFirst application-authenticity security check, which validates the authenticity of the mobile application and thus protects against unlawful attempts to access the application’s resources. The same security check can also be used to protect several resources.

A security check typically issues security challenges that require the client to respond in a specific way to pass the check. This handshake occurs as part of the OAuth access-token-acquisition flow. The client uses challenge handlers to handle challenges from security checks.

Built-in Security Checks

The following predefined security checks are available:

Challenge Handlers

When trying to access a protected resource, the client may be faced with a challenge. A challenge is a question, a security test, a prompt by the server to make sure that the client is allowed to access this resource. Most commonly, this challenge is a request for credentials, such as a user name and password.

A challenge handler is a client-side entity that implements the client-side security logic and the related user interaction. Important: After a challenge is received, it cannot be ignored. You must answer or cancel it. Ignoring a challenge might lead to unexpected behavior.

Learn more about security checks in the Creating a Security Check tutorial, and about challenge handlers in the Credentials Validation tutorial.

Scopes

You can protect resources, such as adapters, from unauthorized access by assigning a scope to the resource.

A scope is defined as a string of one or more space-separated scope elements (“scopeElement1 scopeElement2 …”), or null to apply the default scope (RegisteredClient). The MobileFirst security framework requires an access token for any adapter resource, even if the resource is not assigned a scope, unless you disable resource protection for the resource. See Protecting adapter resources.

Scope Elements

A scope element can be one of the following:

  • The name of a security check.
  • An arbitrary keyword such as access-restricted or deletePrivilege which defines the level of security needed for this resource. This keyword is later mapped to a security check.

Scope Mapping

By default, the scope elements you write in your scope are mapped to a security check with the same name. For example, if you write a security check called PinCodeAttempts, you can use a scope element with the same name within your scope.

Scope Mapping allows to map scope elements to security checks. When the client asks for a scope element, this configuration defines which security checks should be applied. For example, you can map the scope element access-restricted to your PinCodeAttempts security check.

Scope mapping is useful if you want to protect a resource differently depending on which application is trying to access it. You can also map a scope to a list of zero or more security checks.

For example: scope = access-restricted deletePrivilege

  • In app A
    • access-restricted is mapped to PinCodeAttempts.
    • deletePrivilege is mapped to an empty string.
  • In app B
    • access-restricted is mapped to PinCodeAttempts.
    • deletePrivilege is mapped to UserLogin.

To map your scope element to an empty string, do not select any security check in the Add New Scope Element Mapping pop-up menu.

Scope mapping

You can also manually edit the application’s configuration JSON file with the required configuration and push the changes back to a MobileFirst Server.

  1. From a command-line window, navigate to the project’s root folder and run the mfpdev app pull.
  2. Open the configuration file, located in the [project-folder]\mobilefirst folder.
  3. Edit the file by defining a scopeElementMapping property, in this property, define data pairs that are each composed of the name of your selected scope element, and a string of zero or more space-separated security checks to which the element maps. For example:

     "scopeElementMapping": {
         "UserAuth": "UserAuthentication",
         "SSOUserValidation": "LtpaBasedSSO CredentialsValidation"
     }
    
  4. Deploy the updated configuration JSON file by running the command: mfpdev app push.

You can also push updated configurations to remote servers. Review the Using MobileFirst CLI to Manage MobileFirst artifacts tutorial.

Protecting resources

In the OAuth model, a protected resource is a resource that requires an access token. You can use the MobileFirst security framework to protect both resources that are hosted on an instance of MobileFirst Server, and resources on an external server. You protect a resource by assigning it a scope that defines the required permissions for acquiring an access token for the resource.

You can protect your resources in various ways:

Mandatory application scope

At the application level, you can define a scope that will apply to all the resources used by the application. The security framework runs these checks (if exist) in addition to the security checks of the requested resource scope.

Note:

  • The mandatory application scope is not applied when accessing an unprotected resource.
  • The access token that is granted for the resource scope does not contain the mandatory application scope.


In the 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.

Mandatory application scope

You can also manually edit the application’s configuration JSON file with the required configuration and push the changes back to a MobileFirst Server.

  1. From a command-line window, navigate to the project’s root folder and run the mfpdev app pull.
  2. Open the configuration file, located in the project-folder\mobilefirst folder.
  3. Edit the file by defining a mandatoryScope property, and setting the property value to a scope string that contains a space-separated list of your selected scope elements. For example:

    "mandatoryScope": "appAuthenticity PincodeValidation"
    
  4. Deploy the updated configuration JSON file by running the command: mfpdev app push.

You can also push updated configurations to remote servers. Review the Using MobileFirst CLI to Manage MobileFirst artifacts tutorial.

Protecting adapter resources

In your adapter, you can specify the protecting scope for a Java method or JavaScript resource procedure, or for an entire Java resource class, as outlined in the following Java and JavaScript sections. A scope is defined as a string of one or more space-separated scope elements (“scopeElement1 scopeElement2 …”), or null to apply the default scope (see Scopes).

The default MobileFirst scope is RegisteredClient, which require an access token for accessing the resource and verifies that the resource request is from an application that is registered with MobileFirst Server. This protection is always applied, unless you disable resource protection. Therefore, even if you do not set a scope for your resource, it is still protected.

Note: RegisteredClient is a reserved MobileFirst keyword. Do not define custom scope elements or security checks by this name.

Protecting Java adapter resources

To assign a protecting scope to a JAX-RS method or class, add the @OAuthSecurity annotation to the method or class declaration, and set the scope element of the annotation to your preferred scope. Replace YOUR_SCOPE with a string of one or more scope elements (“scopeElement1 scopeElement2 …”):

@OAuthSecurity(scope = "YOUR_SCOPE")

A class scope applies to all of the methods in the class, except for methods that have their own @OAuthSecurity annotation.

Note: When the enabled element of the @OAuthSecurity annotation is set to false, the scope element is ignored. See Disabling Java resource protection.

Examples

The following code protects a helloUser method with a scope that contains UserAuthentication and Pincode scope elements:

@GET
@Path("/{username}")
@OAuthSecurity(scope = "UserAuthentication Pincode")
public String helloUser(@PathParam("username") String name){
    ...
}

The following code protects a WebSphereResources class with the predefined LtpaBasedSSO security check:

@Path("/users")
@OAuthSecurity(scope = "LtpaBasedSSO")
public class WebSphereResources {
    ...
}

Protecting JavaScript adapter resources

To assign a protecting scope to a JavaScript procedure, in the adapter.xml file, set the scope attribute of the <procedure> element to your preferred scope. Replace PROCEDURE_NANE with the name of your procedure, and YOUR SCOPE with a string of one or more scope elements (“scopeElement1 scopeElement2 …”):

<procedure name="PROCEDURE_NANE" scope="YOUR_SCOPE">

Note: When the secured attribute of the <procedure> element is set to false, the scope attribute is ignored. See Disabling JavaScript resource protection.

Example

The following code protects a userName procedure with a scope that contains UserAuthentication and Pincode scope elements:

<procedure name="userName" scope="UserAuthentication Pincode">

Disabling resource protection

You can disable the default MobileFirst resource protection for a specific Java or JavaScript adapter resource, or for an entire Java class, as outlined in the following Java and JavaScript sections. When resource protection is disabled, the MobileFirst security framework does not require a token to access the resource. See Unprotected resources.

Disabling Java resource protection

To entirely disable OAuth protection for a Java resource method or class, add the @OAuthSecurity annotation to the resource or class declaration, and set the value of the enabled element to false:

@OAuthSecurity(enabled = false)

The default value of the annotation’s enabled element is true. When the enabled element is set to false, the scope element is ignored and the resource or resource class is unprotected.

Note: When you assign a scope to a method of an unprotected class, the method is protected despite the class annotation, unless you set the enabled element of the resource annotation to false.

Examples

The following code disables resource protection for a helloUser method:

    @GET
    @Path("/{username}")
    @OAuthSecurity(enabled = "false")
    public String helloUser(@PathParam("username") String name){
        ...
    }

The following code disables resource protection for a MyUnprotectedResources class:

    @Path("/users")
    @OAuthSecurity(enabled = "false")
    public class MyUnprotectedResources {
        ...
    }

Disabling JavaScript resource protection

To entirely disable OAuth protection for a JavaScript adapter resource (procedure), in the adapter.xml file, set the secured attribute of the <procedure> element to false:

<procedure name="procedureName" secured="false">

When the secured attribute is set to false, the scope attribute is ignored and the resource is unprotected.

Example

The following code disables resource protection for a userName procedure:

<procedure name="userName" secured="false">

Unprotected resources

An unprotected resource is a resource that does not require an access token. The MobileFirst security framework does not manage access to unprotected resources, and does not validate or check the identity of clients that access these resources. Therefore, features such as Direct Update, blocking device access, or remotely disabling an application, are not supported for unprotected resources.

Protecting external resources

To protect external resources, you add a resource filter with an access-token validation module to the external resource server. The token-validation module uses the introspection endpoint of the security framework’s authorization server to validate MobileFirst access tokens before granting the OAuth client access to the resources. You can use the MobileFirst REST API for the MobileFirst runtime to create your own access-token validation module for any external server. Alternatively, use one of the provided MobileFirst extensions for protecting external Java resources, as outlined in the Protecting External Resources tutorial.

Authorization flow

The authorization flow has two phases:

  1. The client acquires an access token.
  2. The client uses the token to access a protected resource.

Obtaining an access token

In this phase, the client undergoes security checks in order to receive an access token.

Before the request for an access token the client registers itself with the MobileFirst Server. As part of the registration, the client provides a public key that will be used for authenticating its identity. This phase occurs once in the lifetime of a mobile application instance. If the application-authenticity security check is enabled the authenticity of the application is validated during its registration.

Obtain Token

  1. The client application sends a request to obtain an access token for a specified scope.

    The client requests an access token with a certain scope. The requested scope should map to the same security check as the scope of the protected resource that the client wants to access, and can optionally also map to additional security checks. If the client does not have prior knowledge about the scope of the protected resource, it can first request an access token with an empty scope, and try to access the resource with the obtained token. The client will receive a response with a 403 (Forbidden) error and the required scope of the requested resource.

  2. The client application undergoes security checks according to the requested scope.

    MobileFirst Server runs the security checks to which the scope of the client’s request is mapped. The authorization server either grants or rejects the client’s request based on the results of these checks. If a mandatory application scope is defined, the security checks of this scope are run in addition to the checks of the requested scope.

  3. After a successful completion of the challenge process, the client application forwards the request to the authorization server.

    After successful authorization, the client is redirected to the authorization server’s token endpoint, where it is authenticated by using the public key that was provided as part of the client’s registration. Upon successful authentication, the authorization server issues the client a digitally signed access token that encapsulates the client’s ID, the requested scope, and the token’s expiration time.

  4. The client application receives the access token.

Using a token to access a protected resource

It is possible to enforce security both on resources that run on MobileFirst Server, as shown in this diagram, and on resources that run on any external resource server, as explained in tutorial Using MobileFirst Server to authenticate external resources.

After obtaining an access token, the client attaches the obtained token to subsequent requests to access protected resources. The resource server uses the authorization server’s introspection endpoint to validate the token. The validation includes using the token’s digital signature to verify the client’s identity, verifying that the scope matches the authorized requested scope, and ensuring that the token has not expired. When the token is validated, the client is granted access to the resource.

Protect Resources

  1. The client application sends a request with the received token.
  2. The validation module validates the token.
  3. MobileFirst Server proceeds to adapter invocation.

Tutorials to follow next

Continue reading about authentication in MobileFirst Foundation by following the tutorials from the sidebar navigation.

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 July 02, 2020