Communicating with Approved Widgets

In this section, we'll explore how the conneQt Toolbar interacts with approved widgets and the request format for these widgets.

When your system registers a new widget with the Toolbar (please refer to Widgets Index), you can specify whether the Toolbar should provide context data about the current user and/or patient when the widget is opened. Your design should determine if these contexts are necessary. For instance, if your service doesn't need subject information, it's recommended to register your widget to exclude subject context.

Note

Every time a user launches your widget, an audit record is stored, referencing the data passed via contexts to your widget.

Both user and subject contexts are sent to your system as JSON Web Tokens (JWTs). These tokens are encrypted using the specified encryption secret and algorithm from the request (refer to API Register Widget). For each context requested in your widget's registration, a separate token is included in the request to your widget.

When an HTTP request is made to your endpoint, secure JWTs are included as query string parameters. Your web server can parse and extract data from these tokens.

For instructions on decrypting and using these tokens, please refer to Data Security.

Note

A widget requesting patient data must also request user data. Any registration requests that seek patient data without including user data will be rejected by the Toolbar.

User Context JWT

Each web request to your widget will include a 'user' query string parameter. This parameter's value is a JWT containing data about the authenticated clinical user currently logged into the Toolbar.

https://www.tempuri.com/embedded?user=<user-value>

The 'user-value' placeholder will hold a JWT signed by the Toolbar and encrypted with your system's secret key, provided during widget registration.

The JWT will contain the following list of claims, accessible to your system:

Claim Name Claim Description
iss The name of the conneQt Toolbar system
sub The username of the user as read from their local system
aud The name of your widget as defined through registration
exp The point in time the JWT should no longer be considered valid
iat The point in time the JWT was created
name The full name of the user
org_id* The identifier of the organisation, for NHS organisations this will be their ODS organisation code
org_id_type* The type of identifier carried within the 'org_id' field, for NHS organisations this value is fixed as "OdsOrganisationId"
org_name* The name of the organisation

For NHS users that authenticate with their NHS smartcard the following additional claims are included in the user-value JWT:

Claim Name Claim Description
sds_user_id* The unique identifier for the user
sds_role_profile_id* The unique indetifier for the user's role profile
sds_job_code* The job code of the user
sds_job_title* The text-equivilent of the job code
sds_activity_codes* A list of activity codes for the user's current role
spine_session_id* The user Spine session ID at the time of launching the widget
Note

Claims marked with an asterisk (*) will be prefixed with 'https://toolbar.quicksilva.io/' as they are custom claims.

Sample User JWT:

#JSON Format

{
  "alg": "RS256",
  "kid": "05DA3D54E1E3357EF4A8650EEBEFA4AC45FD07FB",
  "x5t": "Bdo9VOHjNX70qGUO6--krEX9B_s",
  "typ": "JWT"
}
{
  "sub": "local-user",
  "name": "Sam Smith",
  "https://toolbar.quicksilva.io/org_id": "ABC123",
  "https://toolbar.quicksilva.io/org_id_type": "OdsOrganisationId",
  "https://toolbar.quicksilva.io/org_name": "Test GP Practice",
  "https://toolbar.quicksilva.io/sds_user_id": "112233445566",
  "https://toolbar.quicksilva.io/sds_role_profile_id": "998877665544",
  "https://toolbar.quicksilva.io/sds_job_code": "S0080:G0440:R5110",
  "https://toolbar.quicksilva.io/sds_job_title": "Admin Clerical:Admin:Demographic Administrator",
  "https://toolbar.quicksilva.io/sds_activity_codes": "B0168, B0370",
  "https://toolbar.quicksilva.io/spine_session_id": "AQIC5wM2LY4SfcyDjWKqlygGCg5gt7oLHEzIJoDc+96rhPw=@AAJTSQACMDE=#",
  "exp": 1644493243,
  "iat": 1644492643,
  "iss": "https://toolbar.quicksilva.io",
  "aud": "Your Widget Name"
}

#JWT Format

eyJhbGciOiJSUzI1NiIsImtpZCI6IjA1REEzRDU0RTFFMzM1N0VGNEE4NjUwRUVCRUZBNEFDNDVGRDA3RkIiLCJ4NXQiOiJCZG85Vk9Iak5YNzBxR1VPNi0ta3JFWDlCX3MiLCJ0eXAiOiJKV1QifQ.eyJzdWIiOiJsb2NhbC11c2VyIiwibmFtZSI6IlNhbSBTbWl0aCIsImh0dHBzOi8vdG9vbGJhci5xdWlja3NpbHZhLmlvL29yZ19pZCI6IkFCQzEyMyIsImh0dHBzOi8vdG9vbGJhci5xdWlja3NpbHZhLmlvL29yZ19pZF90eXBlIjoiT2RzT3JnYW5pc2F0aW9uSWQiLCJodHRwczovL3Rvb2xiYXIucXVpY2tzaWx2YS5pby9vcmdfbmFtZSI6IlRlc3QgR1AgUHJhY3RpY2UiLCJodHRwczovL3Rvb2xiYXIucXVpY2tzaWx2YS5pby9zZHNfdXNlcl9pZCI6IjExMjIzMzQ0NTU2NiIsImh0dHBzOi8vdG9vbGJhci5xdWlja3NpbHZhLmlvL3Nkc19yb2xlX3Byb2ZpbGVfaWQiOiI5OTg4Nzc2NjU1NDQiLCJodHRwczovL3Rvb2xiYXIucXVpY2tzaWx2YS5pby9zZHNfam9iX2NvZGUiOiJTMDA4MDpHMDQ0MDpSNTExMCIsImh0dHBzOi8vdG9vbGJhci5xdWlja3NpbHZhLmlvL3Nkc19qb2JfdGl0bGUiOiJBZG1pbiBDbGVyaWNhbDpBZG1pbjpEZW1vZ3JhcGhpYyBBZG1pbmlzdHJhdG9yIiwiaHR0cHM6Ly90b29sYmFyLnF1aWNrc2lsdmEuaW8vc2RzX2FjdGl2aXR5X2NvZGVzIjoiQjAxNjgsIEIwMzcwIiwibmJmIjoxNjQ0NDkyNjQzLCJleHAiOjE2NDQ0OTMyNDMsImlhdCI6MTY0NDQ5MjY0MywiaXNzIjoiaHR0cHM6Ly90b29sYmFyLnF1aWNrc2lsdmEuaW8iLCJhdWQiOiJZb3VyIFdpZGdldCBOYW1lIn0.YAstMR-nLE3IDxGKj8C7XpvsqoGQEG8sWUdUVwej-pGIT4ByqsLHnBIfnnezq_m2U8Na60u-ZvxCcxVQr2KgtewcySHycr4pBdUsfdvOQRDmCE_IDubHlqOdalW-VsIbEPfmrgMHgcb-Mg1XpLPTIe1DI8PStgI_4AGc-EdkCEn9TrSIAi9TOzSk_5Axb2GugQhJ9gouzx6SNEEytYyoEUik3krCJaGkrf9gNSK4ZgryiSNxpuwvTGuM1huYfG-sUcd8yIitiQzFUGyk9KgZfKwSrp2_SHcAu-b0_1jQXkSqYku0_nnYDkFHrRtby2phYBYqUWT_A-vS0qFUuFzHPg

Subject Context JWT

If your registration requested access to patient data, each web request to your widget will include a 'subject' query string parameter. This parameter's value is a JWT containing information about the patient currently viewed by the user in a clinical system.

https://www.tempuri.com/embedded?subject=<subject-value>

The 'subject-value' placeholder will contain a JWT signed by the Toolbar and encrypted with your system's secret key, as provided during widget registration.

The JWT will contain the following list of accessible claims for your system:

Claim Name Claim Description
iss The name of the conneQt Toolbar system
sub The identifier of the subject, for NHS patients this will be their NHS Number
sub_type* The type of identifier carried within the 'sub' field, for NHS patients this value is fixed as "VerifiedNhsNumber"
aud The name of your widget as was provided through registration
exp The point in time the JWT should no longer be considered valid
iat The point in time the JWT was created
name The full name of the subject
given_name The first name of the subject
family_name The last name of the subject
email The email address of the subject
phone_number The contact telephone number for the subject
gender The gender of the subject
birthdate The date of birth for the subject
deceaseddate* The date of death for the subject
address The subject's usual address as a single string, each address line is separated by a single line feed character ("\n")
postalcode The post code linked to the address
Note

Claims marked with an asterisk (*) will be prefixed with 'https://toolbar.quicksilva.io/' as they are custom claims.

Sample Subject JWT:

#JSON Format

{
  "alg": "RS256",
  "kid": "05DA3D54E1E3357EF4A8650EEBEFA4AC45FD07FB",
  "x5t": "Bdo9VOHjNX70qGUO6--krEX9B_s",
  "typ": "JWT"
}
{
  "sub": "9587412563",
  "name": "Paula Jones",
  "https://toolbar.quicksilva.io/sub_type": "VerifiedNhsNumber",
  "given_name": "Paula",
  "family_name": "Jones",
  "email": "[email protected]",
  "phone_number": "01249 751 000",
  "gender": "female",
  "birthdate": "1970-04-21",
  "address": "1 test street, test county, UK",
  "postalcode": "Ab1 1AB",
  "nbf": 1644494082,
  "exp": 1644494682,
  "iat": 1644494082,
  "iss": "https://toolbar.quicksilva.io",
  "aud": "Your Widget Name"
}

#JWT Format

eyJhbGciOiJSUzI1NiIsImtpZCI6IjA1REEzRDU0RTFFMzM1N0VGNEE4NjUwRUVCRUZBNEFDNDVGRDA3RkIiLCJ4NXQiOiJCZG85Vk9Iak5YNzBxR1VPNi0ta3JFWDlCX3MiLCJ0eXAiOiJKV1QifQ.eyJzdWIiOiI5NTg3NDEyNTYzIiwibmFtZSI6IlBhdWxhIEpvbmVzIiwiaHR0cHM6Ly90b29sYmFyLnF1aWNrc2lsdmEuaW8vc3ViX3R5cGUiOiJWZXJpZmllZE5oc051bWJlciIsImdpdmVuX25hbWUiOiJQYXVsYSIsImZhbWlseV9uYW1lIjoiSm9uZXMiLCJlbWFpbCI6InRlc3RAcXhsdmEuY29tIiwicGhvbmVfbnVtYmVyIjoiMDEyNDkgNzUxIDAwMCIsImdlbmRlciI6ImZlbWFsZSIsImJpcnRoZGF0ZSI6IjE5NzAtMDQtMjEiLCJhZGRyZXNzIjoiMSB0ZXN0IHN0cmVldCwgdGVzdCBjb3VudHksIFVLIiwicG9zdGFsY29kZSI6IkFiMSAxQUIiLCJuYmYiOjE2NDQ0OTQwODIsImV4cCI6MTY0NDQ5NDY4MiwiaWF0IjoxNjQ0NDk0MDgyLCJpc3MiOiJodHRwczovL3Rvb2xiYXIucXVpY2tzaWx2YS5pbyIsImF1ZCI6IllvdXIgV2lkZ2V0IE5hbWUifQ.lpxA5SoLNNsRZUYf5km_vHB5l5hs7VEoi0NxknlPg3pXnOJzRix8XShnui_urVyZ5zHvsA4GMOJoOc7HYPLchn7T1UzRxyx3W_GYpINVYmAAF0iJ4CBqcfbtheU8d4hlNoMJDYsEBf2SCznh5IfDIH8yDWa6DtCUJv8uUxBazIKbDpZ3w5GImd3MvUq4fD8useEw96-Mok1N2tWXJYGWJlHFXFzVmPpyGcHfKr1gr1LeCRMV0YpoGyLTXXtuopEcY-PUrrb-_pksnJ7faHWlNut5T-A7953nmYB-nqHn597YtLyXJjNBKJNHyNnhizmHr8S04W1JqZ2ODteV5xySIA

Query String Parameters

As mentioned earlier, the URL linking to your endpoint can include 'user' and 'subject' query string parameters. If your widget requested both user and subject contexts, both of these parameters will be present in the URL:

https://www.tempuri.com/embedded?subject=<subject-value>&user=<user-value>

The launch URL you provide in the Register Widget call can already include query string parameters. In this case, the 'user' and 'subject' parameters will be added as additional parameters to the query string.

Note

The Toolbar's query string parameter names are fixed and cannot be used by your system. Registration requests with a launch URL containing 'user' or 'subject' as query string parameters will be rejected by the Toolbar.

Data Security

To ensure secure transmission of user and patient data to your widget, the conneQt Toolbar signs and encrypts all tokens it sends. This section explains this encryption process and how your service can decrypt and utilize these data-containing tokens.

Encryption

When registering your widget, your system provides an encryption secret key to the Toolbar. This shared secret is used for AES-256 encryption and decryption of JWTs. The secret is generated and securely stored by your application, and Quicksilva staff members do not have access to it.

If your application needs to change the secret key, submit a request to the Register Widget endpoint with the new key. The Toolbar will use the new key for encrypting subsequent JWTs, but expect the old key to be used for JWTs already in transit.

When the Toolbar passes user and/or subject context to your widget's endpoint URL, it follows these steps:

  1. Reads context data into a new JWT instance.
  2. Signs the JWT with the Toolbar's private key.
  3. Encrypts the JWT with your provided encryption secret.
  4. Appends a new URL query string parameter to your launch URL.
  5. Makes an HTTP request to the URL created in step 4.

Upon receiving the HTTP request, your server-side code should follow these steps to access the data:

  1. Reads the query string parameter corresponding to the required context.
  2. Decrypts the value using your application's encryption secret key.
  3. Verifies the JWT's signature using the Toolbar public key.
  4. Checks JWT timestamps, ensuring it has not expired.

After completing these steps, your system can access the data within the JWT.

Note

Decrypt the JWT value on your web server, not in the web browser, to maintain the security of your encryption secret key.

Signing

Every JWT generated by the conneQt Toolbar is signed with a private key from a securely held digital certificate within the Toolbar's web server. The corresponding public key is accessible via a public keys request, detailed in Public Keys.

The response to this request contains an array of one or more public keys in JSON Web Key (JWK) format. A JWT is considered valid if its signature can be verified using any of the public keys in the response. During certificate rotation, both old and new certificates' public keys may be present to ensure JWT validity during the transition.

When the Toolbar introduces a new JWT signing certificate, it doesn't immediately switch to it, allowing the older certificate to remain in use for several days until it's phased out. This enables your system to cache the public keys response safely for a period (recommended up to 24 hours) and use it for JWT validation.

Decrypting a JWT received from conneQt

When the conneQt Toolbar launches your system on a clinical user's desktop PC it starts a HTTP GET web request to your web server and includes the requested JWTs as query string parameters. Decryption of a JWT usually follows this flow:

  1. Read the JWT from the URL query string
  2. Download the signing public keys from conneQt
  3. Decrypt the JWT from the query string using your secret key
  4. Verify the JWT has been signed by conneQt

A walk-through of this flow, with sample code in c-sharp, can be found at Decrypting and Reading Claims from a JWT.

See Also