Skip to content

Latest commit

 

History

History
75 lines (63 loc) · 3.34 KB

federatedscript.md

File metadata and controls

75 lines (63 loc) · 3.34 KB

Add the following script to your application's OIDC Server Definition

/**
 * This is a sample authentication callback script for the
 * SMART Outbound Security module, showing federated OAuth2/OIDC Login 
 *
 * @param theOutcome The outcome object. This contains details about the user that was created
 * 	in response to the incoming token.
 * @param theOutcomeFactory A factory object that can be used to create a new success or failure
 * 	object
 * @param theContext The login context. This object contains details about the authorized
 * 	scopes and claims
 * @returns {*} Either a successful outcome, or a failure outcome
 */
 function onAuthenticateSuccess(theOutcome, theOutcomeFactory, theContext) {

    // In this example we are demonstrating a patient-facing app, where the user corresponds to a FHIR Patient, and the
    // ID of that patient is passed back from the federated provider via a claim in the ID Token. Instead
    // the ID might be fetched using an HTTP call, or derived from something else.
    const patientId = theContext.getStringClaim('patientId');

    // Add a log line for troubleshooting
    Log.info("User " + theOutcome.getUsername() + " has authorized for " + patientId + " with scopes: " + theContext.getApprovedScopes());

    // All users can use the FHIR CapabilityStatement operation
    theOutcome.addAuthority('FHIR_CAPABILITIES');

    if (theContext.getStringClaim('role').toLowerCase() === 'superuser') {
        theOutcome.addAuthority('ROLE_SUPERUSER');
        theOutcome.addAuthority('ROLE_FHIR_CLIENT_SUPERUSER');
    }

    if (theContext.getStringClaim('role') === 'general_user') {
        theOutcome.addAuthority('FHIR_READ_ALL_IN_COMPARTMENT', 'Patient/' + patientId);
        theOutcome.addAuthority('FHIR_WRITE_ALL_IN_COMPARTMENT', 'Patient/' + patientId);

        // Despite the name, this operation is only used to grab related resources that are referenced in other FHIR data for the Patient
        // For example, grabbing a Practitioner listed in an ExplanationOfBenefit
        theOutcome.addAuthority('FHIR_OP_PATIENT_EVERYTHING');
    }

    // Basic authorities all users need to have
    theOutcome.addAuthority('FHIR_READ_ALL_OF_TYPE', 'Organization');
    theOutcome.addAuthority('FHIR_READ_ALL_OF_TYPE', 'Location');
    theOutcome.addAuthority('FHIR_READ_ALL_OF_TYPE', 'Practitioner');

    const identifier = theContext.getStringClaim('identifier');
    if (identifier.length > 0) {
        theOutcome.setUserData('federated_detail', identifier);
    }
    // Set the launch context (in case the application has requested a SMART launch context scope). This should only
    // be set if the patient referenced by the ID is actually in context for this launch.  
    theOutcome.addLaunchResourceId('patient', patientId);

    return theOutcome;
}

If you plan on using the User Mapping script section to map usernames from the IDP, you can use the following sample to get started:

/**
 * This is a sample user name mapping callback script
 *
 * @param theOidcUserInfoMap OIDC claims from the token as a map
 * 
 * @param theServerInfo JSON mapping of the OAuth server defintion (backed by ca.cdr.api.model.json.OAuth2ServerJson)
 * 
 * @returns Local unique Smile CDR user name for the enternal user.  
 */
function getUserName(theOidcUserInfoMap, theServerInfo) {
   return "EXT_USER:" + theOidcUserInfoMap['sub'];
}