Skip to content

Self crafted authentication tokens

In some solutions it can make sense to issue JWT tokens on-demand instead of requiring an OpenID Connect compliant Identity Provider to issue JWT tokens. This applies in cases where the customer already have an existing authentication flow, and it is not feasible (technically or economically) to switch to an OpenID Connect compliant (commercial or free) Identity Provider.

❗️ Disclaimer

This document outlines ideas of how this can be accomplished. It does not represent a contract or a decision on specific details of the solution. It also does not specify the total required set of claims.

Given that:

End-users are authenticated safely by an existing authority/service
The existing authentication solution is not already issuing JWT Access (Bearer) tokens
then it is possible for an intermediate middle-layer to bridge the existing authorization and the authorization needed in order to use Vimond Services. This way it is possible to use the Vimond services without any need to first provision the end-user identities in Vimond.

  1. In this flow we assume the client is authenticated by some 3rd party/custom means.
  2. Client invokes an API that requires and verifies the authentication from step 1
  3. Middle-layer crafts a JWT access token and signs it with its private key (RS256). This process includes adding any entitlements relevant to Vimond services that are granted to the subject.
  4. Vimond Service looks up the public key(s) that have been used to sign the token using the .well-known endpoints relative to the issuer URL.

It is key to understand that what uniquely identifies a user from a token is the combination of the issuer (the iss claim) and the subject (the sub claim) from the token. No two users can have the same subject.

There are several ways to handle end users and entitlements,

  1. Using VIA Profiles and VIA montitise for everything including payments.
  2. Using VIA Profiles and VIA montitise and handle payments outside VIA.
  3. Handle all end user management outside VIA, you will need to get the product packages and add to entitlements yourself.

This guide assumes that you are not following recommended practice of using a OIDC compliant identity provider and you are handling end users and payment outside VIA.

This shows how to create JWT tokens, signed with RS256.

As a preparation we need to generate a private/public keypair to sign the token. The first command outputs a public key file suitable for ssh, but we need it to be in PEM format, hence the second command.

Terminal window
ssh-keygen -t rsa -P "" -b 2048 -m PEM -f jwtRS256.key
ssh-keygen -e -m PEM -f jwtRS256.key > jwtRS256.key.pub

Generate a token, using node.js:
The format of the entitlement claims is defined here: Authentication

const fs = require('fs');
const njwt = require('njwt');
var privateKey = fs.readFileSync('./jwtRS256.key');
var claims = {
'sub': '1234567890',
'aud': 'vimond-test-client',
'exp': Math.floor(Date.now() / 1000) + (60 * 60),
'iss': 'https://identity-provider/auth',
'email': 'me@mydomain.com',
'email_verified': true,
'https://vimond/svod': 'id1,id2',
'https://vimond/quality': '4k',
'https://vimond/streamcount': '1',
};
var token = njwt.create(claims, privateKey, 'RS256');
token.setHeader('kid', 'f70wIBkUHr...');
console.log(token.compact());

Remember to resolve the dependencies, e.g using npm and have a package.json with “njwt”: “1.0.0” or higher.

This will output a signed and encoded version of the token similar to the below example.

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJodHRwczovL3ZpbW9uZC9zdm9kIjoiaWQxLGlkMiIsInN1YiI6InNvbWUtc3ViamVjdC1pZCIsImV4cGlyZSI6MTU1MDQ3OTQ5NSwiaWF0IjoxNTUwNDc1ODk1LCJhdWQiOiJpbnRlbmRlZC1hdWRpZW5jZSIsImlzcyI6Imh0dHBzOi8vd3d3LnNvbWVpc3N1ZXIuY29tIn0.ZUE3M4PP9H80mGDZk8uIj5hGbUi0j43ahgTenI3uspbg9ccCOaYTTPEXmaY-AdxsqaVlsNgDC0CnK4K_APJq5MLwPUjp9c3gbxS-0Wtol-4QVVJ2n4Kj4hL0YooPzMaOjN_TK64O9NBeV25YaZANDvJPvMAIeQ_y8cfKSGWYCxf3ZX7zPxPY1o8lEFbEriz4kDmidnYbE-2HflNs6_xvU0jii6Zn1OGi3M_-3lpN5o3_5frS3LC2iq56KY_WA5PsfmuVuElMf-ABR6d-j9ZjqIy_qSbNw_Sz3bhj4Uk4drY2f22Ww-G6xSafHDeyjFDdC17d4wEPtUmd1zFSBdFWjg

Paste the token into jwt.io to do a visual inspection of the generated token.

Vimond services requires the signature to be verified.

The public key needs to be made available through the discovery mechanisms specified in OpenID Connect.

https://www.someissuer.com/.well-known/openid-configuration needs to provide JWT configuration metadata

{
...
"issuer": "https://www.someissuer.com",
"jwks_uri": "https://www.someissuer.com/.well_known/jwks",
...
}

The /jwks endpoint needs to return a JWKS response according to https://tools.ietf.org/html/rfc7517.

This allows the issuer to rotate keys without needing to reconfigure the Vimond services

{
"keys": [
{
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"x5c": [
"MIIC+DCCAeCgAwIBAgIJBIGjYW6hFpn2MA0GCSqGSIb3DQEBBQUAMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTAeFw0xNjExMjIyMjIyMDVaFw0zMDA4MDEyMjIyMDVaMCMxITAfBgNVBAMTGGN1c3RvbWVyLWRlbW9zLmF1dGgwLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMnjZc5bm/eGIHq09N9HKHahM7Y31P0ul+A2wwP4lSpIwFrWHzxw88/7Dwk9QMc+orGXX95R6av4GF+Es/nG3uK45ooMVMa/hYCh0Mtx3gnSuoTavQEkLzCvSwTqVwzZ+5noukWVqJuMKNwjL77GNcPLY7Xy2/skMCT5bR8UoWaufooQvYq6SyPcRAU4BtdquZRiBT4U5f+4pwNTxSvey7ki50yc1tG49Per/0zA4O6Tlpv8x7Red6m1bCNHt7+Z5nSl3RX/QYyAEUX1a28VcYmR41Osy+o2OUCXYdUAphDaHo4/8rbKTJhlu8jEcc1KoMXAKjgaVZtG/v5ltx6AXY0CAwEAAaMvMC0wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUQxFG602h1cG+pnyvJoy9pGJJoCswDQYJKoZIhvcNAQEFBQADggEBAGvtCbzGNBUJPLICth3mLsX0Z4z8T8iu4tyoiuAshP/Ry/ZBnFnXmhD8vwgMZ2lTgUWwlrvlgN+fAtYKnwFO2G3BOCFw96Nm8So9sjTda9CCZ3dhoH57F/hVMBB0K6xhklAc0b5ZxUpCIN92v/w+xZoz1XQBHe8ZbRHaP1HpRM4M7DJk2G5cgUCyu3UBvYS41sHvzrxQ3z7vIePRA4WF4bEkfX12gvny0RsPkrbVMXX1Rj9t6V7QXrbPYBAO+43JvDGYawxYVvLhz+BJ45x50GFQmHszfY3BR9TPK8xmMmQwtIvLu1PMttNCs7niCYkSiUv2sc2mlq1i3IashGkkgmo="
],
"n": "yeNlzlub94YgerT030codqEztjfU_S6X4DbDA_iVKkjAWtYfPHDzz_sPCT1Axz6isZdf3lHpq_gYX4Sz-cbe4rjmigxUxr-FgKHQy3HeCdK6hNq9ASQvMK9LBOpXDNn7mei6RZWom4wo3CMvvsY1w8tjtfLb-yQwJPltHxShZq5-ihC9irpLI9xEBTgG12q5lGIFPhTl_7inA1PFK97LuSLnTJzW0bj096v_TMDg7pOWm_zHtF53qbVsI0e3v5nmdKXdFf9BjIARRfVrbxVxiZHjU6zL6jY5QJdh1QCmENoejj_ytspMmGW7yMRxzUqgxcAqOBpVm0b-_mW3HoBdjQ",
"e": "AQAB",
"kid": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg",
"x5t": "NjVBRjY5MDlCMUIwNzU4RTA2QzZFMDQ4QzQ2MDAyQjVDNjk1RTM2Qg"
}
]}

The individual properties in the structure is defined in JWKS Specification RFC 7517 Section 4.

Entitlements are held in custom claims in the JWT tokens. The specifications for the entitlements claims can be found here Authentication

  • In solutions where both subscription management and issuing tokens are maintained outside the VIA platform, we recommend that also maintaining the entitlements for the user is done outside the platform.
  • If VIA Monetise is used for subscription management, the entitlements are available through documents per user in S3.
  • In the case of a hybrid solution where both VIA Monetise and a third party solution is used, entitlements can be maintained through the Entitlements Sync Service