Skip to main content
Version: 3.13.0-beta.61 (Latest)

Authorization and Authentication

The OHIF Viewer can be configured to work with authorization servers that support one or more of the OpenID-Connect authorization flows. The Viewer finds it's OpenID-Connect settings on the oidc configuration key. You can set these values in your configuration files. For instance you can take a look at our google.js configuration file.

oidc: [
{
// ~ REQUIRED
authority: 'https://accounts.google.com',
client_id: '723928408739-k9k9r3i44j32rhu69vlnibipmmk9i57p.apps.googleusercontent.com',
redirect_uri: '/callback',
response_type: 'id_token token',
scope: 'email profile openid https://www.googleapis.com/auth/cloudplatformprojects.readonly https://www.googleapis.com/auth/cloud-healthcare', // email profile openid
// ~ OPTIONAL
post_logout_redirect_uri: '/logout-redirect.html',
revoke_uri: 'https://accounts.google.com/o/oauth2/revoke?token=',
automaticSilentRenew: true,
revokeAccessTokenOnSignout: true,
},
],

You need to provide the following information:

  • authority: The URL of the authorization server.
  • client_id: The client id of your application (provided by the authorization server).
  • redirect_uri: The callback URL of your application.
  • response_type: The response type of the authorization flow (e.g. id_token token, learn more about different flows).
  • scope: The scopes that your application needs to access
  • post_logout_redirect_uri: The URL that the user will be redirected to after logout.
  • revoke_uri: The URL that the user will be redirected to after logout.
  • automaticSilentRenew: If true, the user will be automatically logged in after the token expires.
  • revokeAccessTokenOnSignout: If true, the access token will be revoked on logout.

How it works

The Viewer uses the userAuthenticationService to set the OpenID-Connect settings. The userAuthenticationService is a singleton service that is responsible for authentication and authorization. It is initialized by the app and you can grab it from the servicesManager

const userAuthenticationService = servicesManager.services.userAuthenticationService;

Then the userAuthenticationService will inject the token as Authorization header in the requests that are sent to the server (both metadata and pixelData).

Token based authentication in URL

Sometimes (although not recommended), some servers like to send the token in the query string. In this case, the viewer will automatically grab the token from the query string and add it to the userAuthenticationService and remove it from the query string (to prevent it from being logged in the console in future requests).

and example would be

http://localhost:3000/viewer?StudyInstanceUIDs=1.2.3.4.5.6.6.7&token=e123125jsdfahsdf

Securing dynamic datasource URLs

When using dicomwebproxy or dicomjson data sources with a runtime ?url=... query parameter, configure explicit trust boundaries to prevent credential exfiltration.

Use these datasource configuration options:

  • dangerouslyAllowedOriginsForAuthenticatedEnvironments: Origin allowlist used only when the viewer is running in an authenticated environment. Entries may use http:// or https:// and can include localhost origins.

Allowed entry format for dangerouslyAllowedOriginsForAuthenticatedEnvironments:

  • Must be a bare origin only: scheme://host[:port]
  • http:// and https:// are both allowed
  • Localhost is allowed when explicitly listed (for example, http://localhost:5000)
  • Must not include username/password, path, query string, or hash
  • Invalid entries are ignored and logged as misconfigured

Policy summary:

  • In unauthenticated environments, any HTTP(S) ?url= origin is allowed.
  • In authenticated environments, ?url= origins must be present in dangerouslyAllowedOriginsForAuthenticatedEnvironments, otherwise loading fails closed.
  • In unauthenticated environments, config URLs are fetched with:
    • method: 'GET'
    • mode: 'cors'
    • credentials: 'omit'
    • redirect: 'error'
    • referrerPolicy: 'no-referrer'
  • In authenticated environments, allowlisted config URLs are fetched using simple fetch behavior.
  • Returned datasource configuration payloads are consumed as-is (no additional URL/config scrubbing).

Example:

dataSources: [
{
namespace: '@ohif/extension-default.dataSourcesModule.dicomwebproxy',
sourceName: 'dicomwebproxy',
configuration: {
name: 'dicomwebproxy',
dangerouslyAllowedOriginsForAuthenticatedEnvironments: [
'https://config.example.com',
'http://localhost:5000',
],
},
},
]

Implicit Flow vs Authorization Code Flow

The Viewer supports both the Implicit Flow and the Authorization Code Flow. The Implicit Flow is the default currently, as it is easier to set up and use. However, you can opt for better security by using the Authorization Code Flow. To do so, add useAuthorizationCodeFlow to the configuration and change the response_type from id_token token to code.

Read more about Implicit Flow vs Authorization Code Flow here and here

oidc: [
{
authority: 'https://accounts.google.com',
client_id: '723928408739-k9k9r3i44j32rhu69vlnibipmmk9i57p.apps.googleusercontent.com',
redirect_uri: '/callback',
scope: 'email profile openid',
post_logout_redirect_uri: '/logout-redirect.html',
revoke_uri: 'https://accounts.google.com/o/oauth2/revoke?token=',
revokeAccessTokenOnSignout: true,
automaticSilentRenew: true,
// CHANGE THESE *****************************
response_type: 'code',
useAuthorizationCodeFlow: true,
},
],

In fact, since browsers are blocking third-party cookies, the Implicit Flow will cease functioning in the future (not specific to OHIF). Read more here. It is recommended to use the Authorization Code Flow and begin migrating to it.

note

For the Authorization Code Flow, when authenticating against Google, you must add the client_secret to the configuration as well. Unfortunately, this seems to occur only with Google.