Skip to content

Inbox authorization

Jakub Miško edited this page Mar 3, 2023 · 2 revisions

This article introduces different types of authorization for Inbox functionality. Inbox persists push messages intended to be read by a particular end user. End users must be authorized, since messages won't be stored for non-authorized users. Authorized end user is an end user who has corresponding profile in People and has "external person id" assigned on that profile.

Mobile Messaging SDK provides 2 ways to request messages from the inbox:

  • Without user authorization. Only for testing environment in sandbox applications
  • With user authorization

Without user authorization

This mode is supported only for "Sandbox" applications on App Profile configuration page and should be used only for testing and demo purposes. It has no additional requirements and it is simple to use. Mobile Messaging SDK will provide messages to any supplied external person id. To enable this mode select the "Application code" radio button in "Inbox authorization type" section on App Profile configuration page

Inbox authorization type - Application code

With user authorization

This mode is more secure and should be used in production although it requires additional effort. In this mode the Mobile Messaging SDK will require a securely signed JSON Web Token (JWT) in order to pass authorization on server side. In order to enable this mode, select the "JSON Web Token (JWT)" radio button in "Inbox authorization type" section on App Profile configuration page

Expected flow

Your mobile application, using Mobile Messaging SDK, should perform the following flow during the end user login or before Inbox request:

Jwt authorization flow diagram

Required structure of JWT

The JWT that was supplied to the Mobile Messaging SDK call is verified on server side before retrieving the inbox for the person with external person id. The required claims and headers for verification are listed in the following table

Header / Claim Description
kid (Header) A standard header that identifies the ID of the secret key used to securely sign the token. The value of this header should be equal to the "secret key id" from the Infobip web interface. The details are explained in the following "Example" chapter.
typ (Claim) A non-standard claim which is still used by the software to verify the type of the token. Should always have "Bearer" value.
sub (Claim) A standard claim that identifies the person that this token was given to. The value of this header is verified to be equal to the external person id of the person, owning the requested Inbox.
infobip-api-key (Claim) A custom claim. The value of this header should be equal to the "Application Code" that can be retrieved from the App Profile configuration page
iat (Claim) A standard claim. This claim is mandatory for the supplied JWT.
exp (Claim) A standard claim. This claim is mandatory for the supplied JWT.
jti (Claim) A standard claim. This claim is mandatory for the supplied JWT.

Example

JWT can be generated multiple ways using different tools. We provide short code snippets in this article that are covering the bare minimum of the JWT claims and headers that are verified by the Infobip system. All examples are using several parameters which are described below.

  • applicationCode parameter is located at the top part of Application Profile configuration. It is visible and can be copied using the icon button:
Application code - copy action
  • keyId and secretKeyHex parameters can be obtained by using the copy icon button of the JWT private keys for mobile app inbox section on the bottom of the App Profile page:
Secret key - copy action
  • externalPersonId parameter uniquely identifies the person in CDP. This parameter should be known by the backend before the token is generated.

Java Example

Java example uses nimbus-jose-jwt as the dependency. Required version of java is 17 because of the HexFormat class, that was added to the java since version 17

import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
 
import java.time.Instant;
import java.util.Date;
import java.util.HexFormat;
import java.util.UUID;
 
public class JwtComposer {
    public String generateSignedJwt(String keyId, String secretKeyHex, String applicationCode, String externalPersonId) throws Exception {
        // simple example how JWT issuing process could look like:
        MACSigner personalizationTokenSigner = new MACSigner(HexFormat.of().parseHex(secretKeyHex));
        JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                .claim("typ", "Bearer")                                     // Mandatory. Type of the token
                .jwtID(UUID.randomUUID().toString())                        // Mandatory. Unique ID of this token
                .subject(externalPersonId)                                  // Mandatory. External Person Id identifying the person in CDP
                .issuer(applicationCode)                                    // Mandatory. Identifier of the issuer. Value is specific to the customer
                .issueTime(new Date())                                      // Mandatory. When this token was issued
                .expirationTime(Date.from(Instant.now().plusMillis(15000))) // Mandatory. When this token should be invalidated
                .claim("infobip-api-key", applicationCode)                  // Mandatory. Custom claim identifying the application, signing the JWT
                .build();
        JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.HS256).type(JOSEObjectType.JWT).keyID(keyId).build();
        SignedJWT personalizedToken = new SignedJWT(jwsHeader, claimsSet);
        personalizedToken.sign(personalizationTokenSigner);
        return personalizedToken.serialize();
    }
}

Node JS Example

Node JS example uses jsonwebtoken and uuid as dependencies. uuid dependency is used only to generate unique JWT ID.

const jwt = require('jsonwebtoken');
const uuid = require('uuid');
 
function generateSignedJWT(keyid, secretKeyHex, applicationCode, externalPersonId) {
    const timestamp = Math.floor(new Date().getTime()/1000);
    const payload = {
        typ: 'Bearer',                     // Mandatory. Type of the token
        jti: uuid.v4(),                    // Mandatory. Unique ID of this token
        sub: externalPersonId,             // Mandatory. External Person Id identifying the person in CDP
        iss: applicationCode,              // Mandatory. Identifier of the issuer. Value is specific to the customer
        iat: timestamp,                    // Mandatory. When this token was issued
        exp: timestamp + 15,               // Mandatory. When this token should be invalidated
        'infobip-api-key': applicationCode // Mandatory. Custom claim identifying the application, signing the JWT
    };
    return jwt.sign(payload, Buffer.from(secretKeyHex, 'hex'), { keyid });
}

Related Articles:

Clone this wiki locally