API Authentication
Accuro REST API Authentication Overview
The Accuro REST API uses OAuth2 as our authentication method. It will be assumed that the users
of this document are familiar with basic OAuth2 flows. More information on the OAuth2 specification can be found here.
There are currently 4 major ways to authenticate with the Accuro API:
- Client Credentials Grants
- Provider Authentication
- Patient Authentication Grant
- Provider Password Grant
This guide covers these authorization flows rather granularly, describing each specific call that is required to authenticate.
It is highly recommended that clients use a library to abstract the authentication away rather than coding these flows from scratch.
The flows are described using cURL only to describe them in a language/tool agnostic way.
Client Credentials
The client credentials authorization is best suited to applications that only require read access to several of the generic public end points such as:
- Offices
- Schedule
- Providers
The Client Credentials flow is the simplest of the OAuth2 Authorization flows.
The specification for the flow can be found here.
The steps to authenticate are:
- Client application requests an access token from the authentication server token end points
- Extract the access token from the response
- Use the access_token to access protected resources
Example:
http://<host_url>:<server_port>/<root>/oauth/authorize?response_type=code&client_id
=<client_id>&redirect_uri=<clients_registered_callback>
- The Provider would then provide their credentials (Accuro Login Credentials)
- The Provider will be asked to approve or deny the client application access to the resources and offices.
- If the resource owner approves, the authentication server will then redirect to the redirect_uri provided and registered to the client and include the code as a query parameter.
- The client must then request an access token from the authentication server using the code provided in the previous step. This code can only be used ONCE and expires in no longer than 10 minutes.
- The access token is requested similar to how a client credentials grant works:
curl -u <client_id>:<client_secret> http://<host>:<port>/<root>/oauth/token -d
‘grant_type=authorization_code’ -d ‘code=<provided_code>’ -d
‘redirect_uri=<client_redirect_url>’ | python -m json.tool
Response:
{
“access_token”: “482a849b-8799-40f9-82b3-3989e214a277”,
“expires_in”: 42675,
“office”: 18225,
“refresh_token”: “8e146849-9d2b-430a-9378-bcee5d3ec6ba”,
“scope”: “CLINICAL_NOTES_READ CLINICAL_NOTES_WRITE CONTACTS_WRITE
GENERATE_TOKEN LABS_READ LABS_WRITE PATIENT_DEMOGRAPHICS_READ
PATIENT_DEMOGRAPHICS_WRITE PORTAL_GENERATE_TOKEN PORTAL_LINK_PATIENT
SCHEDULING_READ SCHEDULING_WRITE”,
“token_type”: “bearer”
}
The access token can then be used for subsequent resource requests.
Notes:
- The request must be a POST
- The token call uses basic authentication with the client_id and client_secret as username/password
- The grant_type parameter must be present in the body and must have the value of authorization_code
- The code parameter must be present in the body and must have the value provided in the query parameters of the redirection from user approval.
- The value of the code parameter can only be used ONCE and expires quickly
- The redirect_uri parameter must be present in the body and must have an identical value to the redirect_uri used in previous steps
When the access_token is about to expire, the refresh_token can be used to request a new access_token
The specification for Refreshing access_tokens can be found here.
Refreshing a token is similar to requesting the access_token
The steps to refresh authentication
- The application will make a call to the token url including the refresh token provided
- The application will extract the new access_token from the result and use it on subsequent resource requests
Example:
curl -u <client_id>:<client_secret> http://<host>:<port>/<root>/oauth/token -d
‘grant_type=refresh_token’ -d ‘refresh_token=<refresh_token_provided>’ | python -m
json.tool
Response:
{
“access_token”: “e2b0d297-264f-4d4d-93e4-de4328726900”,
“expires_in”: 43199,
“office”: 18225,
“refresh_token”: “8e146849-9d2b-430a-9378-bcee5d3ec6ba”,
“scope”: “CLINICAL_NOTES_READ CLINICAL_NOTES_WRITE CONTACTS_WRITE
GENERATE_TOKEN LABS_READ LABS_WRITE PATIENT_DEMOGRAPHICS_READ
PATIENT_DEMOGRAPHICS_WRITE PORTAL_GENERATE_TOKEN PORTAL_LINK_PATIENT
SCHEDULING_READ SCHEDULING_WRITE”,
“token_type”: “bearer”
}
Notes:
- The request must be a POST
- The token call uses basic authentication with the client_id and client_secret as username/password
- The grant_type parameter must be present in the body and must have the value of refresh_grant
- The refresh_token parameter must be present in the body and must have a valid refresh token bound to the requesting client_id
Authentication Grant
The Patient Authentication flow is essentially an Authorization Grant flow (similar to Provider Authentication) using an alternate Authentication Server and requiring a token exchange. Patient Authentication allows access to end points exposing patient information for the authenticated patient such as:
- Demographics
- Labs
- Appointments
Pre-Conditions and Notice
- A Precondition to this Authentication method is some sort of ‘out-of-band’ linking of an IDP User to an Accuro Patient.
- One example of this would be to install Stargate, enable the Medeo module, and have a patient create an appointment and then link the Accuro Patient to the Medeo Patient
- Another example would be however Medeo Patients are looked up and added for Medeo Messaging.
- To Note: The above two flows might need some small tweaks to ensure that the linking of Accuro Patient to IDP user is working properly (i.e. Tickets and development).
- On top of this, the current implementation of patient authentication described below is temporary. Eventually it will be replaced with a simple Authentication flow similar to the Provider Flow above.
The steps to authenticate are:
- Client application directs the resource owner (patient user) to the authorization server login
- The Patient User will authenticate with their credentials.
- If the Patient User authenticates, the authentication server will then redirect to the redirect_uri provided and registered to the client and include the code as a query parameter.
- The client must then request an access token from the authentication server using the code provided in the previous step. This code can only be used ONCE and expires in no longer than 10 minutes.
- The authorization server responds with an access token.
- In the future, this will end the Patient Authentication Flow, and the access token returned by the above call will be useable for future calls But for now there are some extra steps.
- The client application must then convert the access_token from IDP to a Rest API Access token.
- The client application will need to obtain a client credentials grant from the Rest API. See the instructions above.
- The client application must then make a post to:
http://<host>:<port>/accapi/rest/v1/portal/token?officeId=<officeId>
- The client application must include the access_token bare in the request body with a content type of application/json
- The client application must include the officeId as a query parameter.
- The access_token and refresh_token can then be extracted from the response body and used on subsequent requests (including refresh).
Example:
- Client Application Directs the Patient User to the Authentication Server login page below:
# This call uses the medeo staging environment, in production in would be
id.medeohealth.com
https://s-id.medeohealth.com/oauth/authorize?response_type=code&client_id=<client_id>&redirect_uri=<clients_registered_callback>
- If authentication is successful, the client application will be redirected to the redirect_uri provided, with the code query parameter.
- The client saves the code parameter and ignores other parameters.
- The client must then request an access token from the authentication server using the code provided in the previous step. This code can only be used ONCE and expires in no longer than 10 minutes.
- The client application then requests an access_token similar to flows described previously.
curl -u <client_id>:<client_secret> http://s-id.medeohealth.com/oauth/token -d
‘grant_type=authorization_code’ -d ‘code=<provided_code>’ -d
‘redirect_uri=<client_redirect_url>’ | python -m json.tool
Response:
{
“access_token”:
“eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJyZXNvdXJjZV9vd25lcl9pZCI6NDUyMTksInNjb3Blc
yI6WyJwdWJsaWMiXSwiYXBwbGljYXRpb24iOnsidWlkIjoiMjFlNzllYjY3YTBlMDY0NWU0M2Q1MTZlYWMz
ZDQ5NDMwNWQ5ZTNkMmMxMmJkNmU3NWU4NmVlYjA4ZWQyZTNiOCIsInByaXZpbGVnZWQiOnRydWV9LCJleHA
iOjE0OTYxODY5ODUsIm5vbmNlIjoiYjAzYTM0YWExOTc2ZGY5MzIwZWMxZjcyYWJmODViOGMifQ.U155hHT
PycX9zCEiitnAO5CRNxxjbgN2sNFLjC6A-LsLjkHym7UIJX6r7LquXlIOeMSuLnOgdKZgMJNmBI0jKR6HRh
tk8I0Ojw4a8sRrcCVRPij971gbnX92-kKEJMyCvTa37QQdgbcfJXCcYggQ62vzLGnP0KP4ApncH8n3b1alg
rIUjTtX828QALiz88SLaoLEM6o4ZpTT_c8xX3A_p15zhUmu4_To5wwFCJ6f8MmJgJ7_AbgWZ5qT3_z4LGG7
4w0a-j-_qMh8BtycOS85mHcSp4YPh84eV-YsTEv-UEpOtGDisYbqblFuQ57rIphcmo9QxdPJt5Fiw_emlgc
CEVr4FaZCVfcAz8aJe9nHWzOtwz1TBlnYCIZc5rJCFn6mOWab3o8POwikg-un_laDeNDzIJjpmDhF4ycaqF
SVPoJR_HVVl8nOCOw8xlF16OJ2xcd5f2Ldh_s1SnYSxFEvUc9-k91Yb5DymxDTInCPMAYVxwEBbLNbf_bNI
h86Bm4DY4TPGhpKGL0pIjqPCZFod4EAhFHl_tPHO7KZJmIQguAGQwirbiuEWeGytUxI8JZxfaLTAOxWYcZi
u6NmkbDB1WepFgB4dngPW0vRC_DhL5VbyVSSrEJB7VWnsaz8yYO3TBX-O6DWf3cqBIqMVarkdeN4KpMtmIL
1SoyyZQyhcZo”,
“created_at”: 1496179785,
“expires_in”: 7200,
“refresh_token”:
“c795c7c68cea3978b26a700e4c0b4cedadf2d8bd6aa1cb3316a8c42339ade48f”,
“scope”: “public”,
“token_type”: “bearer”
}
- The client application must now request an access token from Rest API Authentication Server for this patient.
- The client should store the access_token returned in the body of the above request
- The client should obtain a client credentials grant from the Rest API using the instructions above.
- The client should make a post to the Rest API with the access_token in the body:
curl -H ‘Authorization:Bearer <client_credential_grant>’ -H
‘Content-Type:application/json’
‘http://localhost:9090//<root>/rest/v1/portal/token?officeId=<officeId>’ -d
‘<access_token_from_above>’ | python -m json.tool
Response:
{
“patientId”: 6,
“firstName”: “Bryan”,
“lastName”: “Bergen”,
“middleName”: “”,
“email”: {
“address”: “bryan.bergen@qhrtech.com”,
“order”: 0
},
“address”: {
“street”: “”,
“city”: “”,
“postalZip”: ” “,
“locationId”: 1
},
“token”: {
“access_token”: “7624727d-8baa-4032-9410-b2ab033e9afc”,
“token_type”: “bearer”,
“refresh_token”: “55f09c3a-423d-478e-828e-ee3999e1fe3d”,
“expires_in”: 43199,
“scope”: “CLINICAL_NOTES_READ CLINICAL_NOTES_WRITE CONTACTS_WRITE
GENERATE_TOKEN LABS_READ LABS_WRITE PATIENT_DEMOGRAPHICS_READ
PATIENT_DEMOGRAPHICS_WRITE PORTAL_GENERATE_TOKEN PORTAL_LINK_PATIENT
SCHEDULING_READ SCHEDULING_WRITE”,
“office”: 18226
}
}
- The access_token and the refresh_token from the above response can then be used for subsequent requests and refreshes as outlined in previous steps.
Notes:
- The main difference in the Authorization Grant portion of this flow is that it uses IDP (https//id.medeohealth.com/) as the authentication server as opposed to the Rest API itself.
- In the exchange POST to the API the content type must be set to application/json or the call will fail.
- In the exchange POST to the API the office id must be supplied as a query parameter or the call will fail.
- In the future, the token exchange portion of this flow will cease to be necessary. Client applications will be able to directly use the IDP access_token and refresh_token.
Provider Password Grant
The Provider Password Grant is suited for cases where the resource owner has a trust relationship with the client. Not all clients will have access to this grant type and other authorization should be preferred. Providers authenticated by this grant will have the same level of access as if they had used the Provider Authorization Grant flow with the same scopes.
Provider Password Grant uses the OAuth2 Password Credentials Flow.
The specification for the flow can be found here.
The steps to authenticate are:
- The Client application obtains the resource owners credentials. How these are obtained is beyond the scope of the Accuro API. The client must discard the credentials once an access token has been obtained by this grant flow See Oauth2 Spec Here.
- The Client application makes a request to the token end point.
- Extract the access token from the response.
- Use the access_token to access protected resources.
Example:
curl -u <client_id>:<client_secret>
http://<host_url>:<server_port>/<root>/oauth/token -d ‘grant_type=password’ -d
“username=<accuro_username>” -d “password=<accuro_password>” -d “office=<office_id>”
| python -m json.tool
Response:
{
“access_token”: “cd2b74af-e7eb-4223-a2f2-f78201e44a5d”,
“token_type”: “bearer”,
“refresh_token”: “85007352-8472-4ab2-b221-fe3a722c4949”,
“expires_in”: 40402,
“scope”: “LABS_READ SCHEDULING_READ SCHEDULING_WRITE”
}
Notes:
- The request must be a post
- The call to /oauth/token uses Basic Authentication with client id and client secret as the username/password combination
- The content-type of the request must be application/x-www-form-urlencoded
- The form content MUST contain the following key value pairs:
– grant-type: password
– username: The Accuro User’s username for the Provider
– password: The Accuro User’s password
– office: The office id the resource owner wishes to authenticate to. If the provider has no roles in this office, a 401 Unauthorized Response will be returned. - The form content MAY contain the following optional or environment dependent key value pairs:
– scope: Space delimited list of requested scopes. Any invalid scopes will result in a 400 Bad Request Response being returned.
– tenant: Required in HOSTED configurations, ignored elsewhere. - The refresh token can be used as described above.