Skip to main content

Authorization

OpenEMR uses OIDC compliant authorization for API. SSL is required and setting baseurl at Administration->Globals->Connectors->'Site Address (required for OAuth2 and FHIR)' is required. The listing of scopes can be found in below Scopes section.

Scopes

This is a listing of scopes:

api:oemr (user api which are the /api/ endpoints)
user/allergy.read
user/allergy.write
user/appointment.read
user/appointment.write
user/dental_issue.read
user/dental_issue.write
user/document.read
user/document.write
user/drug.read
user/encounter.read
user/encounter.write
user/facility.read
user/facility.write
user/immunization.read
user/insurance.read
user/insurance.write
user/insurance_company.read
user/insurance_company.write
user/insurance_type.read
user/list.read
user/medical_problem.read
user/medical_problem.write
user/medication.read
user/medication.write
user/message.write
user/patient.read
user/patient.write
user/practitioner.read
user/practitioner.write
user/prescription.read
user/procedure.read
user/soap_note.read
user/soap_note.write
user/surgery.read
user/surgery.write
user/vital.read
user/vital.write
api:fhir (user fhir which are the /fhir/ endpoints)
user/AllergyIntolerance.read
user/CareTeam.read
user/Condition.read
user/Encounter.read
user/Immunization.read
user/Location.read
user/Medication.read
user/MedicationRequest.read
user/Observation.read
user/Organization.read
user/Organization.write
user/Patient.read
user/Patient.write
user/Practitioner.read
user/Practitioner.write
user/PractitionerRole.read
user/Procedure.read
api:port (patient api which are the /portal/ endpoints) (EXPERIMENTAL)
patient/encounter.read
patient/patient.read
api:pofh (patient fhir which are the /portalfhir/ endpoints) (EXPERIMENTAL)
patient/Encounter.read
patient/Patient.read
Registration
  • Here is an example for registering a client. A client needs to be registered before applying for grant to obtain access/refresh tokens.
  • Note: "post_logout_redirect_uris" is optional and only used if client wants a redirect to its own confirmation workflow.
  • Note that all scopes are included in this example for demonstration purposes. For production purposes, should only include the necessary scopes.
curl -X POST -k -H 'Content-Type: application/json' -i https://localhost:9300/oauth2/default/registration --data '{
"application_type": "private",
"redirect_uris":
["https://client.example.org/callback"],
"post_logout_redirect_uris":
["https://client.example.org/logout/callback"],
"client_name": "A Private App",
"token_endpoint_auth_method": "client_secret_post",
"contacts": ["me@example.org", "them@example.org"],
"scope": "openid api:oemr api:fhir api:port api:pofh user/allergy.read user/allergy.write user/appointment.read user/appointment.write user/dental_issue.read user/dental_issue.write user/document.read user/document.write user/drug.read user/encounter.read user/encounter.write user/facility.read user/facility.write user/immunization.read user/insurance.read user/insurance.write user/insurance_company.read user/insurance_company.write user/insurance_type.read user/list.read user/medical_problem.read user/medical_problem.write user/medication.read user/medication.write user/message.write user/patient.read user/patient.write user/practitioner.read user/practitioner.write user/prescription.read user/procedure.read user/soap_note.read user/soap_note.write user/surgery.read user/surgery.write user/vital.read user/vital.write user/AllergyIntolerance.read user/CareTeam.read user/Condition.read user/Encounter.read user/Immunization.read user/Location.read user/Medication.read user/MedicationRequest.read user/Observation.read user/Organization.read user/Organization.write user/Patient.read user/Patient.write user/Practitioner.read user/Practitioner.write user/PractitionerRole.read user/Procedure.read patient/encounter.read patient/patient.read patient/Encounter.read patient/Patient.read"
}'

Response:

{
"client_id": "LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA",
"client_secret": "j21ecvLmFi9HPc_Hv0t7Ptmf1pVcZQLtHjIdU7U9tkS9WAjFJwVMav0G8ogTJ62q4BATovC7BQ19Qagc4x9BBg",
"registration_access_token": "uiDSXx2GNSvYy5n8eW50aGrJz0HjaGpUdrGf07Agv_Q",
"registration_client_uri": "https:\/\/localhost:9300\/oauth2\/default\/client\/6eUVG0-qK2dYiwfYdECKIw",
"client_id_issued_at": 1604767861,
"client_secret_expires_at": 0,
"contacts": ["me@example.org", "them@example.org"],
"application_type": "private",
"client_name": "A Private App",
"redirect_uris": ["https:\/\/client.example.org\/callback"],
"token_endpoint_auth_method": "client_secret_post",
"scope": "openid api:oemr api:fhir api:port api:pofh user/allergy.read user/allergy.write user/appointment.read user/appointment.write user/dental_issue.read user/dental_issue.write user/document.read user/document.write user/drug.read user/encounter.read user/encounter.write user/facility.read user/facility.write user/immunization.read user/insurance.read user/insurance.write user/insurance_company.read user/insurance_company.write user/insurance_type.read user/list.read user/medical_problem.read user/medical_problem.write user/medication.read user/medication.write user/message.write user/patient.read user/patient.write user/practitioner.read user/practitioner.write user/prescription.read user/procedure.read user/soap_note.read user/soap_note.write user/surgery.read user/surgery.write user/vital.read user/vital.write user/AllergyIntolerance.read user/CareTeam.read user/Condition.read user/Encounter.read user/Immunization.read user/Location.read user/Medication.read user/MedicationRequest.read user/Observation.read user/Organization.read user/Organization.write user/Patient.read user/Patient.write user/Practitioner.read user/Practitioner.write user/PractitionerRole.read user/Procedure.read patient/encounter.read patient/patient.read patient/Encounter.read patient/Patient.read"
}

  • SMART on FHIR Registration

  • SMART Enabled Apps are supported.

  • SMART client can be registered at /interface/smart/register-app.php. For example https://localhost:9300/interface/smart/register-app.php

  • After registering the SMART client, can then Enable it in OpenEMR at Administration->System->API Clients

  • After it is enabled, the SMART App will then be available to use in the Patient Summary screen (SMART Enabled Apps widget).

See this github issue for an example of a Smart App installation: #4148

Authorization Code Grant

This is the recommended standard mechanism to obtain access/refresh tokens. This is done by using an OAuth2 client with provider url of

oauth2/<site>; 

An example full path would be

https://localhost:9300/oauth2/default.

Refresh Token Grant

Example:

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
-i 'https://localhost:9300/oauth2/default/token'
--data 'grant_type=refresh_token
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&refresh_token=def5020089a766d16...'

Response:

{
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYn...",
"token_type": "Bearer",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYnl1RkRp...",
"refresh_token": "def5020017b484b0add020bf3491a8a537fa04eda12..."
}

Password Grant

  • Recommend not using this mechanism unless you know what you are doing.

  • It is considered far less secure than the standard authorization code method.

  • Because of security implications, it is not turned on by default. It can be turned on at

  • Administration->Globals->Connectors->'Enable OAuth2 Password Grant (Not considered secure)'.

Note that all scopes are included in these examples for demonstration purposes. For production purposes, should only include the necessary scopes.

Example for users role:

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
-i 'https://localhost:9300/oauth2/default/token'
--data 'grant_type=password
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&scope=openid%20api%3Aoemr%20api%3Afhir%20user%2Fallergy.read%20user%2Fallergy.write%20user%2Fappointment.read%20user%2Fappointment.write%20user%2Fdental_issue.read%20user%2Fdental_issue.write%20user%2Fdocument.read%20user%2Fdocument.write%20user%2Fdrug.read%20user%2Fencounter.read%20user%2Fencounter.write%20user%2Ffacility.read%20user%2Ffacility.write%20user%2Fimmunization.read%20user%2Finsurance.read%20user%2Finsurance.write%20user%2Finsurance_company.read%20user%2Finsurance_company.write%20user%2Finsurance_type.read%20user%2Flist.read%20user%2Fmedical_problem.read%20user%2Fmedical_problem.write%20user%2Fmedication.read%20user%2Fmedication.write%20user%2Fmessage.write%20user%2Fpatient.read%20user%2Fpatient.write%20user%2Fpractitioner.read%20user%2Fpractitioner.write%20user%2Fprescription.read%20user%2Fprocedure.read%20user%2Fsoap_note.read%20user%2Fsoap_note.write%20user%2Fsurgery.read%20user%2Fsurgery.write%20user%2Fvital.read%20user%2Fvital.write%20user%2FAllergyIntolerance.read%20user%2FCareTeam.read%20user%2FCondition.read%20user%2FEncounter.read%20user%2FImmunization.read%20user%2FLocation.read%20user%2FMedication.read%20user%2FMedicationRequest.read%20user%2FObservation.read%20user%2FOrganization.read%20user%2FOrganization.write%20user%2FPatient.read%20user%2FPatient.write%20user%2FPractitioner.read%20user%2FPractitioner.write%20user%2FPractitionerRole.read%20user%2FProcedure.read
&user_role=users
&username=admin
&password=pass'

Example for patient role:

curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
-i 'https://localhost:9300/oauth2/default/token'
--data 'grant_type=password
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&scope=openid%20api%3Aport%20api%3Apofh%20patient%2Fencounter.read%20patient%2Fpatient.read%20patient%2FEncounter.read%20patient%2FPatient.read
&user_role=patient
&username=Phil1
&password=phil
&email=heya@invalid.email.com'

Response:

{
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYn...",
"token_type": "Bearer",
"expires_in": 3599,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYnl1RkRp...",
"refresh_token": "def5020017b484b0add020bf3491a8a537fa04eda12..."
}

Logout

  • A grant (both Authorization Code and Password grants) can be logged out (ie. removed) by url of
oauth2/<site>/logout?id_token_hint=<id_token>;

An example full path would be

https://localhost:9300/oauth2/default/logout?id_token_hint=<id_token>. 

  • Optional: post_logout_redirect_uri and state parameters can also be sent; note that post_logout_redirect_uris also needs to be set during registration for it to work.

More Details

The forum thread that detailed development of Authorization and where questions and issues are addressed is here:

https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450

More specific development api topics are discussed and described on the above forum thread (such as introspection).