Authentication and Security
Overview
The PMF 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, PMF functions also as the authorization server. However, you can configure an IBM WebSphere DataPower appliance to act as the authorization server and interact with PMF.
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:
Authorization entities
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
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.
- 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 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
- From a command-line window, navigate to the project's root folder and run the
pmfdev app pull
. - Open the configuration file, located in the [project-folder]\mobilefirst folder.
- Edit the file by defining a
maxTokenExpiration
property and set its value to the maximum access-token expiration period, in seconds: - Deploy the updated configuration JSON file by running the command:
pmfdev app push
.
- From a command-line window, navigate to the project's root folder and run the
Close section
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:
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-levelWLAuthorizationManager
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-levelWLResourceRequest
class, which encapsulates the OAuth flow for accessing protected resources, the security framework handles the Confidential clients.
Close section
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
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
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,
Use different bundle ids for different platforms.
Close section
Following is an example of a valid refresh token response from the authorization server:
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.
Close section
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
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
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 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.
Scope Elements
A scope element can be one of the following:
- The name of a security check.
- An arbitrary keyword such as
access-restricted
ordeletePrivilege
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 toPinCodeAttempts
.deletePrivilege
is mapped to an empty string.
- In app B
access-restricted
is mapped toPinCodeAttempts
.deletePrivilege
is mapped toUserLogin
.
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.
You can also manually edit the application’s configuration JSON file with the required configuration and push the changes back to a PMF.
- From a command-line window, navigate to the project’s root folder and run the
pmfdev app pull
. - Open the configuration file, located in the [project-folder]\mobilefirst folder.
-
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" }
- 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 tutorial.
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
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 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.
You can also manually edit the application’s configuration JSON file with the required configuration and push the changes back to a PMF.
- From a command-line window, navigate to the project’s root folder and run the
pmfdev app pull
. - Open the configuration file, located in the project-folder\mobilefirst folder.
-
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"
- 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 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 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. 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
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 PMF 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 PMF 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 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
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 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 tutorial.
Authorization flow
The authorization flow has two phases:
- The client acquires an access token.
- 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 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.
-
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.
-
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.
-
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.
-
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 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.
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.
- The client application sends a request with the received token.
- The validation module validates the token.
- PMF proceeds to adapter invocation.
Tutorials to follow next
Continue reading about authentication in PMF by following the tutorials from the sidebar navigation.
▲- Creating a Security Check
- CredentialsValidationSecurityCheck
- Implementing the challenge handler in Ionic applications
- Implementing the CredentialsValidationSecurityCheck class
- Implementing the challenge handler in JavaScript (Cordova, Web) applications
- Implementing the challenge handler in iOS applications
- Implementing the challenge handler in Android applications
- Implementing the challenge handler in Ionic applications
- UserAuthenticationSecurityCheck
- Implementing the ExternalizableSecurityCheck
- Step Up Authentication
- Enrollment
- LTPA-based single sign-on (SSO) security check
- Application Authenticity
- Confidential Clients
- Configuring Device Single Sign-On (SSO)
- Using Mobile Foundation Server to authenticate external resources
- Certificate Pinning
- Configuring the Mobile Foundation Server Keystore