Authentication and Security

## Overview {: #overview } The PMF security framework is based on the [OAuth 2.0](http://oauth.net/) 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, PMF functions also as the **authorization server**. The client application can then use these tokens to access resources on a **resource server**, which can be either the PMF 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 PMF. 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: {: #jump-to } * [Authorization entities](#authorization-entities) * [Protecting resources](#protecting-resources) * [Authorization flow](#authorization-flow) * [Tutorials to follow next](#tutorials-to-follow-next) ## Authorization entities {: #authorization-entities } ### Access Tokens {: #access-tokens } A PMF 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 {: #structure } The PMF 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](#mandatory-application-scope). * **Token-expiration time**: the time at which the token becomes invalid (expires), in seconds. #### Token expiration {: #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 PMF 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 pmfdev app pull.
    2. Open the configuration file, located in the [project-folder]\pmf 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: pmfdev 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 Confidential clients.

### Refresh Tokens {: #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. #### Persistent Mobile Foundation Refresh Token {: #mfp-refresh-token} A PMF 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 PMF access token, the PMF 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 {: #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. > > PMF supports refresh token feature on iOS. ### Security Checks {: #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 PMF 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 {: #built-in-security-checks } The following predefined security checks are available: - [Application Authenticity](application-authenticity/) - [LTPA-based single sign-on (SSO)](ltpa-security-check/) - [Direct Update](../../installation-configuration/production/post-install/application-development/direct-update) ### Challenge Handlers {: #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](creating-a-security-check/) tutorial, and about challenge handlers in the [Credentials Validation](credentials-validation) tutorial. ### Scopes {: #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 PMF 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](#protecting-adapter-resources ). #### Scope Elements {: #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 {: #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 PMF. 1. From a **command-line window**, navigate to the project's root folder and run the `pmfdev app pull`. 2. Open the configuration file, located in the **[project-folder]\pmf** 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: ```xml "scopeElementMapping": { "UserAuth": "UserAuthentication", "SSOUserValidation": "LtpaBasedSSO CredentialsValidation" } ``` 4. Deploy the updated configuration JSON file by running the command: `pmfdev app push`. > You can also push updated configurations to remote servers. Review the [Using PMF CLI to Manage PMF artifacts](../../application-development/using-mobilefirst-cli-to-manage-mobilefirst-artifacts) tutorial. ## Protecting resources {: #protecting-resources } In the OAuth model, a protected resource is a resource that requires an access token. You can use the PMF security framework to protect both resources that are hosted on an instance of PMF, 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 {: #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](#unprotected-resources). * The access token that is granted for the resource scope does not contain the mandatory application scope.
In the PMF 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 PMF. 1. From a **command-line window**, navigate to the project's root folder and run the `pmfdev app pull`. 2. Open the configuration file, located in the **project-folder\pmf** 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: ```xml "mandatoryScope": "appAuthenticity PincodeValidation" ``` 4. Deploy the updated configuration JSON file by running the command: `pmfdev app push`. > You can also push updated configurations to remote servers. Review the [Using PMF CLI to Manage PMF artifacts](../../application-development/using-mobilefirst-cli-to-manage-mobilefirst-artifacts) tutorial. ### Protecting adapter resources {: #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](#protecting-java-adapter-resources) and [JavaScript](#protecting-javascript-adapter-resources) 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](#scopes)). The default PMF 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 PMF. This protection is always applied, unless you [disable resource protection](#disabling-resource-protection). Therefore, even if you do not set a scope for your resource, it is still protected. > Note: `RegisteredClient` is a reserved PMF keyword. Do not define custom scope elements or security checks by this name. #### Protecting Java adapter resources {: #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](#disabling-java-resource-protection). ##### Examples {: #java-adapter-resource-protection-examples } The following code protects a `helloUser` method with a scope that contains `UserAuthentication` and `Pincode` scope elements: ```java @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: ```java @Path("/users") @OAuthSecurity(scope = "LtpaBasedSSO") public class WebSphereResources { ... } ``` #### Protecting JavaScript adapter resources {: #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 ..."): ```xml ``` Note: When the `secured` attribute of the <procedure> element is set to false, the `scope` attribute is ignored. See [Disabling JavaScript resource protection](#disabling-javascript-resource-protection). #### Example {: #javascript-adapter-resource-protection-examples } The following code protects a `userName` procedure with a scope that contains `UserAuthentication` and `Pincode` scope elements: ```xml ``` ### Disabling resource protection {: #disabling-resource-protection } You can disable the [default PMF resource protection](#protecting-adapter-resources) for a specific Java or JavaScript adapter resource, or for an entire Java class, as outlined in the following [Java](#disabling-java-resource-protection) and [JavaScript](#disabling-javascript-resource-protection) sections. When resource protection is disabled, the PMF security framework does not require a token to access the resource. See [Unprotected resources](#unprotected-resources). #### Disabling Java resource protection {: #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`: ```java @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](#unprotected-resources). 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 {: #disabling-java-resource-protection-examples } The following code disables resource protection for a `helloUser` method: ```java @GET @Path("/{username}") @OAuthSecurity(enabled = "false") public String helloUser(@PathParam("username") String name){ ... } ``` The following code disables resource protection for a `MyUnprotectedResources` class: ```java @Path("/users") @OAuthSecurity(enabled = "false") public class MyUnprotectedResources { ... } ``` #### Disabling JavaScript resource protection {: #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`: ```xml ``` When the `secured` attribute is set to `false`, the `scope` attribute is ignored and the resource is [unprotected](#unprotected-resources). ##### Example {: #disabling-javascript-resource-protection-examples } The following code disables resource protection for a `userName` procedure: ```xml ``` ### Unprotected resources {: #unprotected-resources } An unprotected resource is a resource that does not require an access token. The PMF 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 {: #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 PMF access tokens before granting the OAuth client access to the resources. You can use the [PMF REST API for the PMF runtime](../../api/rest/runtime) to create your own access-token validation module for any external server. Alternatively, use one of the provided PMF extensions for protecting external Java resources, as outlined in the [Protecting External Resources](protecting-external-resources) tutorial. ## Authorization flow {: #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 {: #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 PMF. 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](auth-flow-1.jpg) 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. > PMF 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 {: #using-a-token-to-access-a-protected-resource } It is possible to enforce security both on resources that run on PMF, as shown in this diagram, and on resources that run on any external resource server, as explained in tutorial [Using PMF to authenticate external resources](protecting-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](auth-flow-2.jpg) 1. The client application sends a request with the received token. 2. The validation module validates the token. 3. PMF proceeds to adapter invocation. ## Tutorials to follow next {: #tutorials-to-follow-next } Continue reading about authentication in PMF by following the tutorials from the sidebar navigation.
Last modified on