Skip to content

FHIR Authorization

As described in the SMART on FHIR Authorization Flow, to make API calls to the Kodjin FHIR Server API, the client application provides an access token as a bearer token.

The access token SHALL be obtained during the authorization flow by calling the authorization endpoint on the authorization server. The link for the authorization endpoint can be found here.

For applications that use a two-legged authentication (system-to-system), an access token can be obtained by directly calling the token endpoint. Applications that use a three-legged authentication must first call the authorization endpoint to request and obtain an end user's consent. The token endpoint response for three-legged authentication applications may also contain an ID token, refresh token, or launch context.

A proof key for code exchange (PKCE) is disabled in this version of the implementation

Authorize the client

The authorization endpoint is used for end user login, limits scopes requested by application, and gives consent. These actions are prerequisites to requesting an access token. This endpoint SHOULD be obtained from the authorization endpoint, which temporarily redirects the end user to the Kodjin FHIR Server API login where the user is asked to log in or get automatically authenticated using an existing session. The user is then prompted for scope limitations and consent form. Afterwards, the user is redirected back to the application requesting the access token with an authorization code. The app then provides this authorization code to the token endpoint to obtain an access token.

The flow described above is a browser flow only because the authorization server will redirect the user's browser to the provided redirect URL.

METHOD GET

GET [authorization_endpoint]?response_type=code&client_id=[client_id]&redirect_uri=[redirect_uri]&scope=[scope]&state=[state]&aud=[aud]

PARAMS

  • authorization_endpoint - authorization endpoint SHALL be observed from the FHIR base url authorization observation endpoint.
  • client_id - client ID for registered developers application.
  • redirect_url - url for for developers application which browser redirect after successfull authorization. Must exactly match a redirect URI configured for the developers application client credentials during registration.
  • scope - requested optional scopes by application delimited by space, case sensitive. At a minimum, the client must request the OpenID Connect scope (openid) for successful authentication and to obtain an ID token in the token endpoint response. To obtain a refresh token in the token endpoint response, the client must request the offline_access scope. To perform a SMART app launch sequence, the client must request either the launch or launch/patient scope (for provider EHR launch or patient standalone launch) in addition to resource-level scopes for those FHIR endpoints you will access through your app launch. Details about scopes.
  • state - a one-time use arbitrary string provided by developers application (client) and subsequently returned by the authorized endpoint. The intent of this parameter, per OAuth specification, is for applications to compare the request and response values to prevent cross-site request forgery attacks.
  • aud - FHIR base URL, used to specify the organization for which the end user will be authenticated.

RESPONSES

  • code - authorization code generated by Kodjin FHIR Server API authorization server and required to make a token request.
  • state - identical value to the state parameter provided in client app’s authorize request.

Example

https://demo.kodjin.com/auth/realms/fhir/protocol/openid-connect/auth?response_type=code&client_id=my-app&redirect_uri=https%3A%2F%2Fmy.app.com%2Fsuites%2Fcustom%2Fsmart%2Fredirect&scope=launch%2Fpatient+openid+fhirUser+offline_access+patient%2FMedication.read+patient%2FAllergyIntolerance.read+patient%2FCarePlan.read+patient%2FCareTeam.read+patient%2FCondition.read+patient%2FDevice.read+patient%2FDiagnosticReport.read+patient%2FDocumentReference.read+patient%2FEncounter.read+patient%2FGoal.read+patient%2FImmunization.read+patient%2FLocation.read+patient%2FMedicationRequest.read+patient%2FObservation.read+patient%2FOrganization.read+patient%2FPatient.read+patient%2FPractitioner.read+patient%2FProcedure.read+patient%2FProvenance.read+patient%2FPractitionerRole.read+patient%2FServiceRequest.read&state=e75c105d-04b4-47e6-b4af-a36773cc2600&aud=https%3A%2F%2Fdemo.kodjin.com%2Ffhir

Access token

Obtain an access token. The token endpoint is used for two-legged authorization applications. This method only works if the client supports this type of authorization.

METHOD POST

[token_endpoint]

PARAMS

[token_endpoint url] - token endpoint SHALL be observed from the FHIR base url authorization observation endpoint.

BODY

Body SHALL be provided as Content-Type: application/x-www-form-urlencoded.

  • client_id - ID for the client-registered app
  • grant_type - 'client_credentials'
  • client_secret - client secret for the registered app
  • scope - requested optional scopes delimited by space (e.g., patient/*.read launch/patient)

HEADERS

The authorization token SHALL be obtained during the authentication and authorization process. Refer to authentication and authorization for further details.

Header Type Required/Optional Value
Content-Type string required application/x-www-form-urlencoded

RESPONSES

Code Description Comment
200 OK The request was processed successfully, and the access token was returned.
400 Bad request Invalid request parameters, e.g., client ID or grant type.
401 Unauthorized Invalid client secret.
404 no Route matched with those values The request was able to communicate with a given server, but the server could not find what was requested.
500 Internal Server Error The server has encountered a situation it doesn't know how to handle.

The body will contain the JSON request response. If the token was obtained successfully, the body SHALL contain:

  • access_token - signed base64 JWT access token
  • expires_in - time in seconds until token expiration date
  • refresh_expires_in - time in seconds until token expiration date
  • token_type - Type: Barear
  • scope - list of the granted default client's scope

Example - Access token

eyJhbGciOiJSUzI1NiIs2nRqcCIgOiAiSldUIiwia2lkIiA6ICJMcEZjdWVzMzJqUFRkaF9pOFNVY0I1Tk5HenNQZD24REc0SHZNQTlIVXJvIn0.eyJleHAiOjE2NjYsNDQ5NDIsImlhdCI6MTY2NjU0NDY0MiwianRpIjoiNzRhNDIxN2QtN2VhYi00NWNmLTgxYjktNGFhNDhmM2U4NmU1IiwiaXNzIjoiaHR0cHM6Ly9zYW5kYm94LmZoaXIuZWxhdGlvbmVtci5jb20vYXV0aC9yZWFsbXMvZmhpciIsInN1YiI6IjEwZGZhY2RjLWIxNmYtNDI5OS1hY2M4LWM3Y2M4YTE3NDlhMiIsanR5cCI6IkJlYXJlciIsImF6cCI6ImluZmVybm8iLCJhY3IiOiIxIiwic2NvcGUiOiJsYXVuY2gvcGF0aWVudCIsImNsaWVudElkIjoiaW5mZXJubyIsImNsaWVudEhvc3QiOiIxMC4xLjEwLjExMCIsImNsaWVudEFkZHJlc3MiOiIxMC4xLjEwLjExMCIsImdyb3VwIjpbXX0.U8Q9zcFo_JeQIA2UG8j42Bu9eLASuF4D_hSJ-mPy6HT6xJ_9huSYa4FkkpFZ5gKKZQx7dTmye3qbwqyFBDrOWMZ1Z2lrh9DXXq6vP6FgSdyzqAu-Xvj-WdKdOXBsQ8gNP5LDg-PVdiMqNTne7uWJkX3CIv9mYOz72KjJf8GvGFDdKvArIN-t3aKFYR9Y41XGRqi9eph-91PbpZygZ4HcVjhM2nY8mR4EoKai5MQUtB6S8Y8VRkTaxpivcreXVe15YQ-34_rwcFjXczhCemmo4poVxWcpT-PU8bf1Obum_yKlNE1uJrTA223Knd_auyFUszyYm-xoCIJA6KxkoWsHew

Token Introspection

Endpoint to check the token’s status and the metadata content of a JWT token.

METHOD POST

POST [introspection_endpoint]

PARAMS

[introspection_endpoint] - token introspection endpoint url SHALL be observed from the FHIR base url

BODY

Body SHALL provide as x-www-form-url-encoded

  • client_id - ID for the client-registered app
  • client_secret - client secret for the registered app
  • token - token value for the introspection

HEADERS

The authorization token SHALL be obtained during the authentication and authorization process. Go to authentication and authorization for further details.

Header Type Required/Optional Value
Content-Type string required application/x-www-form-urlencoded

RESPONSES

Code Description Comment
200 OK The request was processed successfully, and an access token was returned.
400 Bad request Invalid request parameters, e.g., client ID or grant type.
401 Unauthorized Invalid client secret.
404 no Route matched with those values The request was able to communicate with a given server, but the server could not find what was requested.
500 Internal Server Error The server has encountered a situation it doesn't know how to handle.

The body will contain the JSON request response. If the token was obtained successfully, the body SHALL contain:

  • active - true or false. If the token is active, additional token information will be provided.
  • exp - time until token expiration date (seconds since Unix epoch)
  • iat - time when token was issued (seconds since Unix epoch)
  • jti - JWT ID, unique token ID
  • sub - list of the granted default client's scope
  • iss - token issuer and signer
  • typ - type of the token
  • azp - client (application)
  • acr - authentication context class
  • scope - granted scopes for the token
  • clientId - optional client ID
  • clientHost - optional host
  • clientAddress - optional host

Example

curl --location --request POST 'https://demo.kodjin.com/auth/realms/fhir/protocol/openid-connect/token/introspect' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: cookie=f9dd0e1484656621' \
--data-urlencode 'token=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJMcEZjdWVzMzJqUFRkaF9pOFNVY0I1Tk5HenNQZDF4REc0SHZNQTlIVXJvIn0.eyJleHAiOjE2NjY1NTI3NTcsImlhdCI6MTY2NjU1MjQ1NywianRpIjoiZWI3NWNmZWUtZDQ2NS00OGFkLWI5MTAtMzBhYjFmOTcxNTZhIiwiaXNzIjoiaHR0cHM6Ly9zYW5kYm94LmZoaXIuZWxhdGlvbmVtci5jb20vYXV0aC9yZWFsbXMvZmhpciIsInN1YiI6IjEwZGZhY2RjLWIxNmYtNDI5OS1hY2M4LWM3Y2M4YTE3NDlhMiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImluZmVybm8iLCJhY3IiOiIxIiwic2NvcGUiOiJsYXVuY2gvcGF0aWVudCIsImNsaWVudElkIjoiaW5mZXJubyIsImNsaWVudEhvc3QiOiIxMC4xLjEwLjExMCIsImNsaWVudEFkZHJlc3MiOiIxMC4xLjEwLjExMCIsImdyb3VwIjpbXX0.CBORAyD25vahskhUbzb-MXXG2KzNIXd_h30IpquvRdvCb5p0CyVbIlNk3dKUXdH9Axrmq5tT8iwbeZDeeRQQYLUdrgy_S8VTQnpquLRwS9PUqccGtH0hYIEwwwFgkyol3CibBh0jb9RFF5q9_JYpa_TSnpIiF7hvNLuevjK_OveUcBwa0ZJqt6shx4sI9po6JyHA3kmJwG5p-LRp6I-aZoc2DWkxk0F-LRfFAiv4m19xkLDMKHOsYSJ9ybqK-5h78YewATC9t1hrprczVFPaz0enBGmWwLIb0N_v5s354lo4JTAROCXcOKjIL3CORH0GuOcdR1clLGvi42LmGSAFvA' \
--data-urlencode 'client_id=my-app' \
--data-urlencode 'client_secret=67dmuHxjqdCh32r3itbPVIMhOREhXbOs'
{
"exp": 1666552757,
"iat": 1666552457,
"jti": "eb75cfee-d465-48ad-b910-30ab1f97156a",
"iss": "https://demo.kodjin.com/auth/realms/fhir",
"sub": "10dfacdc-b16f-4199-acc8-c7cd8a1749a2",
"typ": "Bearer",
"azp": "my-app",
"acr": "1",
"scope": "launch/patient",
"clientId": "my-app",
"clientHost": "192.168.10.110",
"clientAddress": "192.168.10.110",
"group": [],
"client_id": "my-app",
"username": "service-account-my-app",
"active": true
}

Token revocation

The token revocation is a mechanism for clients to indicate to the Kodjin FHIR Server API authorization server that an access token is no longer needed. This is used to enable a "log out" feature in clients, allowing the authorization server to clean up any security credentials associated with the authorization.

METHOD POST

POST [revocation_endpoint]

PARAMS

[revocation_endpoint] - token revocation endpoint URL SHALL be observed from the FHIR base URL authorization observation endpoint

BODY

Body SHALL provide as x-www-form-url-encoded

  • client_id - ID for the client registered app
  • client_secret - client secret for the registered app
  • token - token value for the revocation

HEADERS

The Authorization token SHALL be obtained during Authentication and Authorization process. Goto Authentication and Authorization for further details.

Header Type Required/Optional Value
Content-Type string required application/x-www-form-urlencoded

RESPONSES

Code Description Comment
200 OK The request was processed successfully, and the token was revoked.
400 Bad request Invalid request parameters, e.g., client ID or client_secret or token.
404 no Route matched with those values The request was able to communicate with a given server, but the server could not find what was requested.
500 Internal Server Error The server has encountered a situation it doesn't know how to handle.

Example - Request

curl --location --request POST 'https://demo.kodjin.com/auth/realms/fhir/protocol/openid-connect/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: cookie=f9dd0e1484656621' \
--data-urlencode 'client_id=my-app' \
--data-urlencode 'client_secret=bdmuHxjqMdh3Pr3itbLVIMhOREhXbOs' \
--data-urlencode 'token=eyJhbGciOiJSUzI1wiIsS1nR5cCIgOiAiSldUIiwia2lkIiA6ICJMcEZjdWVzMzJqUFRkaF9pOFNVY0I1Tk5HenNQZDF4REc0SHZNQTlIVXJvIn0.eyJleHAiOjE2NjY1NTI3NTcsImlhdCI6MTY2NjU1MjQ1NywianRpIjoiZWI3NWNmZWUtZDQ2NS00OGFkLWI5MTAtMzBhYjFmOTcxNTZhIiwiaXNzIjoiaHR0cHM6Ly9zYW5kYm94LmZoaXIuZWxhdGlvbmVtci5jb20vYXV0aC9yZWFsbXMvZmhpciIsInNsYiI6IjEwZGZhY2RjLWIxNmYtNDI5OS1hY2M4LWM3Y2M4YTE3NDlhMiIsInR5cCI6IkJlYXJlciIsImF6cCI6ImluZmVybm8iLCJhY3IiOiIxIiwic2NvcGUiOiJsYXVuY2gvcGF0aWVudCIsImNsaWVudElkIjoiaW5mZXJubyIsImNsaWVudEhvc3QiOiIxMC4xLjEwLjExMCIsImNsaWVudEFkZHJlc3MiOiIxMC4xLjEwLjExMCIsImdyb3VwIjpbXX0.CBORAyD25vahskhUbzb-MXXG2KzNIXd_h30IpquvRdvCb5p0CyVbIlNk3dKUXdH9Axrmq5tT8iwbeZDeeRQQYLUdrgy_S8VTQnpquLRwS9PUqccGtH0hYIEwwwFgkyol3CibBh0jb9RFF5q9_JYpa_TSnpIiF7hvNLuevjK_OveUcBwa0ZJqt6shx4sI9po6JyHA3kmJwG5p-LRp6I-aZoc2DWkxk0F-LRfFAiv4m19xkLDMKHOsYSJ9ybqK-5h78YewATC9t1hrprczVFPaz0enBGmWwLIb0N_v5s354lo4JTAROCXcOKjIL3CORH0GuOcdR1clLGvi42LmGSAFvA'