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:
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 secretrequireProofKey(true)— PKCE S256 required on every authorize requestrequireAuthorizationConsent(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
2. Consent Manager — add Immunization scopes
In SmartConsentCustomizer, two entries have already been added to SCOPE_TO_RESOURCE:
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.rsas a valid SMART scope string - The Consent Manager can create consent records that cover Immunization resources
- The
SmartScopeAuthorizationInterceptoron HAPI recognisespatient/Immunization.rsas 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.