Skip to main content

Platform Registration

The Immunisation App needs to be registered in two places: the Auth Server (OAuth2 client registration) and the Consent Manager (scope map). Both changes are already in the codebase — they just need to be enabled.

1. Auth Server — register the client

In akhester-smart-fhir-server, the DataInitializer contains a documented stub for the immunization app registration. Enable it by uncommenting the code block:

DataInitializer.java
if (!appRepo.existsByClientId("aj-fhir-immunization")) {
RegisteredApp immApp = new RegisteredApp(
"aj-fhir-immunization",
"AJ FHIR Immunisation App",
"http://localhost:8084/callback",
"launch,launch/patient,openid,fhirUser,offline_access," +
"patient/Patient.rs,patient/Immunization.rs,patient/ImmunizationRecommendation.rs"
);
appRepo.save(immApp);
log.info("Immunization app registered — client_id=aj-fhir-immunization");
}

Or insert directly into the database at runtime (no restart required):

INSERT INTO registered_apps (client_id, app_name, redirect_uri, allowed_scopes, active)
VALUES (
'aj-fhir-immunization',
'AJ FHIR Immunisation App',
'http://localhost:8084/callback',
'launch,launch/patient,openid,fhirUser,offline_access,patient/Patient.rs,patient/Immunization.rs,patient/ImmunizationRecommendation.rs',
true
);

What the registration does

The JpaRegisteredClientRepository converts this RegisteredApp to a Spring Authorization Server RegisteredClient with:

  • ClientAuthenticationMethod.NONE — public client, no client secret
  • requireProofKey(true) — PKCE S256 required on every authorize request
  • requireAuthorizationConsent(false) — auto-approve in the portal (consent is handled by the Consent Manager, not the OAuth2 consent screen)
  • AuthorizationGrantType.REFRESH_TOKEN — enables offline token refresh

In SmartConsentCustomizer, two entries have already been added to SCOPE_TO_RESOURCE:

SmartConsentCustomizer.java
java.util.Map.entry("patient/Immunization.rs",                "Immunization"),
java.util.Map.entry("patient/ImmunizationRecommendation.rs", "ImmunizationRecommendation"),

This means:

  • The VALID_SCOPE regex accepts patient/Immunization.rs as a valid SMART scope string
  • The Consent Manager can create consent records that cover Immunization resources
  • The SmartScopeAuthorizationInterceptor on HAPI recognises patient/Immunization.rs as a valid scope for read access to Immunization resources

No further changes to the Consent Manager are needed.

3. Docker Compose — add the service

Add to your docker-compose.yml:

immunization:
image: ajfhir/immunization:1.0.0
ports:
- "8084:8084"
environment:
SMART_CLIENT_ID: aj-fhir-immunization
SMART_REDIRECT_URI: http://localhost:8084/callback
AUTH_SERVER_URL: http://auth-server:9000
FHIR_BASE_URL: http://hapi-fhir:8080/fhir
depends_on:
- hapi-fhir
- auth-server
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8084/actuator/health"]
interval: 30s
start_period: 60s
networks:
- smart-net

4. Verify the registration

After starting, confirm the app appears in the auth server database:

psql -U smartfhir -c "SELECT client_id, app_name, active FROM registered_apps WHERE client_id='aj-fhir-immunization';"
       client_id        |        app_name         | active
------------------------+-------------------------+--------
aj-fhir-immunization | AJ FHIR Immunisation App | t

Then do a test launch from http://localhost:9000/portal — select any patient and click Launch App. If the browser redirects to http://localhost:8084/launch?iss=..., the registration is working.


Configuration · Architecture →