OZO FHIR implementation guide
0.1.0 - ci-build
OZO FHIR implementation guide - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
The procedure for parsing the request headers is as follows:
Authorization header from the request.Bearer
or DPoP.
^(Bearer|DPoP) (.+)$Bearer, only the access_token should be extracted and validated.DPoP, the DPoP header should be extracted and validated additionally to the access_token.The access_token can be validated by sending a request to the introspection endpoint of the authorization server. The
request should include the access_token as a parameter as part of a application/x-www-form-urlencoded request. The
response will contain information about the token, such as its validity and the subject it represents.
baseUrl, from internal NUTS url: example https://nuts-node-int.example.comaccess_token, the access token to validate from the requestexport async function introspect(base_url: string, access_token: string) {
const url = `${base_url}/internal/auth/v2/accesstoken/introspect`
return await fetch(url, {
method: "POST",
body: 'token=' + encodeURIComponent(access_token),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then((data) => data.json())
}
{
"active": true,
"client_id": "https://nuts-node.example.com/oauth2/roland_test",
"cnf": {
"jkt": "fuu....GHQ"
},
"exp": 1733852948,
"iat": 1733852048,
"iss": "https://nuts-node.example.com/oauth2/ozo",
"scope": "ozo"
}
active field should be true, mind that the response status will be 200 even if the token is not valid.scope field should match the use case of the token.iss must match the {base_url}/oauth2/{subject} where the base_url is the external URL of the NUTS node and
the subject is the OZO system subject.client_id should match the expected client id.cnf the field jkt, the value MUST be used for the DPoP header validation. If
no DPoP header is present, an error MUST be thrown and the validation MUST fail.dpop_header, the DPoP header of the request.thumbprint, the thumbprint from the introspection response at the field cnf.jkt.access_token, the access_token from the Authorization header of the request.request_url, the URL of the request.request_method, the HTTP method from the request, such as GET or POST.export async function valudate_dpop(base_url: string, access_token: string, dpop_header:string, cnfJkt: string, request_url: string, request_method: string) {
const url = `${base_url}/internal/auth/v2/dpop/validate`
const data = {
"dpop_proof": dpop_header,
"thumbprint": cnfJkt,
"token": access_token,
"url": request_url,
"method": request_method
}
return await fetch(url, {
method: "POST",
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
}).then((data) => data.json())
}
{
"valid": true
}
active field should be true, mind that the response status will be 200 even if the token is not valid.