Publish SMART on FHIR OAuth2 URLs using Azure API Management
Fast Healthcare Interoperable Resources (FHIR) is an emerging standard for describing healthcare data (Resources) and an API for exchanging healthcare information. I have written several blog posts on running Firely FHIR servers in Azure and HAPI FHIR servers in Azure. I have also described that you can use Azure API Management in front of a FHIR server.
SMART on FHIR is a tech stack for applications that build on the FHIR standard. It provides a framework and guidance on how applications should interact with Electronic Health Records (EHR) systems. Among other specific guidance, SMART on FHIR lays out the authentication/authorization flows bases on OAuth2. In a previous blog post, I discussed how Azure Active Directory could be used for SMART on FHIR authorization through a proxy. In this blog post I will add to this scenario by showing how Azure API Management can be used to publish the authorization and token endpoints for SMART on FHIR.
The SMART on FHIR security information can be included in the conformance statement. This statement is generally available through the /metadata
endpoint on the FHIR server. In order to modify the body of the message returned from the FHIR server, you can modify the outbound policy on the /metadata
endpoint:
Depending on your backend FHIR server and the way that you imported the API, the /metadata
endpoint may not be there. You can simply add a new endpoint pointing to the same path on the backend. In the outbound
policy, you can modify the body of the message using the set-body
tag:
[xml]
<policies>
<inbound>
<base />
</inbound>
<backend>
<base />
</backend>
<outbound>
<set-body>
<!-- TEXT OF BODY -->
</set-body>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
[/xml]
The part where the "TEXT OF BODY" is generated can simply be replaced with the following C# snippet, where we add the authorize
and token
endpoints for SMART on FHIR:
[plain]
@{
var response = context.Response.Body.As<JObject>();
var rest = ((JArray)response["rest"])[0] as JObject;
var security = JObject.Parse(@"{
'service': [
{
'coding': [
{
'system': 'https://hl7.org/fhir/restful-security-service',
'code': 'SMART-on-FHIR'
}
],
'text': 'OAuth2 using SMART-on-FHIR profile (see https://docs.smarthealthit.org)'
}
],
'extension': [
{
'url': 'https://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris',
'extension': [
{
'url': 'token',
'valueUri': 'https://smart-on-fhir-login.azurewebsites.net/microsoft.onmicrosoft.com/oauth2/token'
},
{
'url': 'authorize',
'valueUri': 'https://smart-on-fhir-login.azurewebsites.net/microsoft.onmicrosoft.com/oauth2/authorize'
}
]
}
]
}");
rest.Add("security", security);
return response.ToString();
}
[/plain]
You should, of source replace the specific URLs to match your server. And that is it, you have now leveraged Azure API Management to update the conformance statement with the appropriate authorization endpoints.
Let me know if you have questions/comments/suggestions.