Exposing mobile services to non-mobile (confidential) clients

Using IBM MobileFirst™ Platform Foundation you can let a confidential (or non-mobile) client connect to mobile services in a secure way. For example, you can grant a back-end service access to the Push service.

Overview

The confidential client flow is based on the client credentials flow, as defined in the OAuth specification. The client authenticates with the authorization server using a certificate. The authentication server validates the certificate, and if it is valid, issues an access token to the client. The certificate has to be signed by a trusted signer certificate that is configured at the authorization server.

Structure of the client certificate

The confidential client certificate contains three attributes that are required for the token generation:
  • Client ID: a string that identifies the confidential client, that is, the certificate holder. The client ID is used to identify the client, for example for collecting analytics.
  • Scope: a list of scope tokens (realm names) that can be granted to the certificate holder. Unlike realms that are used by mobile clients, the realms for certificate holders do not have to be defined in the authenticationConfig.xml security configuration file of the application. Built-in MobileFirst realms and realms that are defined in the security configuration file may also be included.
  • Expiration: the expiration time (in seconds) of tokens that are generated for the certificate holder.
The Client ID attribute is stored as the common name attribute of the certificate. The Scope and Expiration attributes are stored as X.509 certificate extensions. A sample script has been provided that generates a certificate with these three attributes, and signs it with the trusted signer certificate. For more information, see Generating the trusted signer certificate.

Acquiring tokens

To acquire a token, the client authenticates itself with the authorization server by providing a JSON Web Signature (JWS). The payload of the JWS contains a timestamp and is signed by the certificate of the confidential client. The signature is valid for one minute only, meaning that clients must generate a new signature with every token request.

The client posts a token request to the authorization server's token endpoint. The request includes the signature that allows the server to authenticate the client. The request might also include a Scope parameter that specifies the scope to be granted in the token. The Scope parameter has to be a subset of the scope that is defined in the certificate of the client. If no scope is included in the request, the result token is an access token that includes no realms (but this is still a valid token).

If the signature is verified correctly, the server responds with an access token. The access token is generated using the attributes that are specified in the certificate - the client ID, the token expiration, and the scope (or a subset of the scope if specified in the scope parameter of the token request). The expiration time of the individual realms is the same as the token expiration time.

The sample application, Confidential_Client_Sample can be used for constructing a signature, sending a request to the token endpoint, and extracting the access token from the response. Download Confidential_Client_Sample.

Generating a client certificate

A sample script has been provided for generating a certificate for a confidential client. The script puts the custom attributes (Client ID, Scope, and Expiration) in the certificate and signs the certificate with the trusted signer certificate. The script uses OpenSSL, so ensure that you have OpenSSL installed. The script is called gen_cert.sh.

The gen_cert.sh script requires three parameters:
  • Workdir: the path of the working directory. The script uses two files that must be present in the working directory: rootCA.crt, the trusted signer certificate, and rootCA.key, the private key of the trusted signer certificate.
  • clientId: the client ID attribute to be stored in the certificate.
  • password: the password for protecting the private key of the client certificate and the resulting KeyStore.
The scope and expiration attributes to be placed in the certificate are taken from the configuration file extensions.cnf that is located in the directory of the script. Before running the script, edit this file and set the values for scope and expiration.
The script generates the following files:
  • certificate.crt: the client certificate.
  • private_key.key: the private key of the client certificate.
  • keystore.p12: a PKCS #12 KeyStore that stores the client certificate and the private key.

Download the Certificate_Scripts sample script.

Generating the trusted signer certificate

You can generate the trusted signer certificate by creating a certificate-signing request and submitting it to a chosen certificate authority. The trusted signer certificate may also be self-signed. A sample script, gen_root_cert.sh generates a self-signed signer certificate. It requires a single parameter - the path of the output directory. The script generates two files: rootCA.crt, the signer certificate, and rootCA.key, the private key of the certificate. The default password is abcdef, but it can be changed by editing the script. The script is included in Certificate_Scripts.zip.

Configuring the trusted signers

The list of trusted signer certificates is configured in the property trusted.signer.certificate.paths. The list is space-separated. The paths may be relative to the server folder in the MobileFirst Project (for example: conf/rootCA.crt), or absolute paths.

Sample client project

You can download Confidential_Client_Sample, as a zip file. The sample project contains code for obtaining an access token by generating a JSON web signature, and submitting a request to the token endpoint. The sample project contains a KeyStore file, keystore.p12 that was generated with the sample script gen_cert.sh. The KeyStore contains a client certificate that is signed with the sample signer certificate (rootCA.crt, located in the zip file). The scope attribute of the client certificate has the value scope1 scope2 scope3, and the sample code shows a request for a token with scope scope1, which is a subset of the scope that is defined in the certificate. To run the sample, perform the following steps:
  1. Configure the authorization server to use the root certificate rootCA.crt as a trusted signer. Put the certificate file rootCA.crt inside your MobileFirst Platform project and set the value of the property trusted.signer.certificate.paths accordingly. For example, if you put the root certificate in the conf directory of your MobileFirst Platform project, the property value is trusted.signer.certificate.paths=conf/rootCA.crt.
  2. Edit the constant MFP_PROJECT_URL in the source file ConfidentialClientSample.java, and replace the host, the protocol, and the MobileFirst Platform project name with the appropriate values. Run the ConfidentialClientSample Java™ application. The application requests an access token from the authorization server and prints it to the console.