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.

SMART retrieval and refresh sequence

pic