App exchanges authorization code for access token
After obtaining an authorization code, the app trades the code for an access
token via HTTP POST to the EHR authorization server's token endpoint URL,
using content-type application/x-www-form-urlencoded, as described in
section 4.1.3 of RFC6749](https://tools.ietf.org/html/rfc6749#page-29).
For public apps, authentication is not
possible (and thus not required), since the app cannot be trusted to protect a
secret. For confidential apps, an
Authorization header using HTTP Basic authentication is required, where the
username is the app's client_id and the password is the app's client_secret
(see example).
| Parameters | ||
|---|---|---|
grant_type |
required | Fixed value: authorization_code |
code |
required | Code that the app received from the authorization server |
redirect_uri |
required | The same redirect_uri used in the initial authorization request |
client_id |
conditional | Required for public apps. Omit for confidential apps. |
The EHR authorization server SHALL return a JSON structure that includes an access token or a message indicating that the authorization request has been denied. The JSON structure includes the following parameters:
| Parameters | ||
|---|---|---|
access_token |
required | The access token issued by the authorization server |
token_type |
required | Fixed value: Bearer |
expires_in |
recommended | Lifetime in seconds of the access token, after which the token SHALL NOT be accepted by the resource server |
scope |
required | Scope of access authorized. Note that this can be different from the scopes requested by the app. |
state |
required | The exact value received from the client in the authorization request |
id_token |
optional | Authenticated patient identity and profile, if requested |
refresh_token |
optional | Token that can be used to obtain a new access token, using the same or a subset of the original authorization grants |
In addition, if the app was launched from within a patient context,
parameters to communicate the context values MAY BE included. For example,
a parameter like "patient": "123" would indicate the FHIR resource
https://[fhir-base]/Patient/123. Other context parameters may also
be available. For full details see SMART launch context parameters.
The parameters are included in the entity-body of the HTTP response, as described in section 5.1 of RFC6749.
The access token is a string of characters as defined in
RFC6749 and
RFC6750. The token is essentially
a private message that the authorization server
passes to the FHIR Resource Server, telling the FHIR server that the
"message bearer" has been authorized to access the specified resources.
Defining the format and content of the access token is left up to the
organization that issues the access token and holds the requested resource.
The authorization server's response MUST include the HTTP "Cache-Control" response header field with a value of "no-store," as well as the "Pragma" response header field with a value of "no-cache."
The EHR authorization server decides what expires_in value to assign to an
access token and whether to issue a refresh token, as defined in section 1.5
of RFC6749, along with the
access token. If the app receives a refresh token along with the access
token, it can exchange this refresh token for a new access token when the
current access token expires (see step 5 below). A refresh token MUST
BE bound to the same client_id and MUST contain the same, or a subset of,
the set of claims authorized for the access token with which it is associated.
Apps SHOULD store tokens in app-specific storage locations only, not in system-wide-discoverable locations. Access tokens SHOULD have a valid lifetime no greater than one hour, and refresh tokens (if issued) SHOULD have a valid lifetime no greater than twenty-four hours. Confidential clients may be issued longer-lived tokens than public clients.
A large range of threats to bearer tokens can be mitigated by digitally
signing the token as specified in RFC7515
or by using a Message Authentication Code (MAC) instead. Alternatively,
a bearer token can contain a reference to authorization information,
rather than encoding the information directly into the token itself.
To be effective, such references must be infeasible for an attacker to
guess. Using a reference may require an extra interaction between the
resource server and the authorization server; the mechanics of such an
interaction are not defined by this specification.
For example
Given an authorization code, the app trades it for an access token via HTTP
POST.
Request for
POST /token HTTP/1.1
Host: ehr
Authorization: Basic bXktYXBwOm15LWFwcC1zZWNyZXQtMTIz
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=123abc&
redirect_uri=https%3A%2F%2Fapp%2Fafter-auth
Response
{
"access_token": "i8hweunweunweofiwweoijewiwe",
"token_type": "bearer",
"expires_in": 3600,
"scope": "patient/Observation.read patient/Patient.read",
"state": "98wrghuwuogerg97",
"intent": "client-ui-name",
"patient": "123",
"encounter": "456"
}
At this point, the authorization flow is complete. Follow steps below to work with data and refresh access tokens, as shown in the following sequence diagram.