25.20.1Machine to Machine Authentication

 

Smile provides the ClientAuthInterceptor to create interceptors to handle SMART on FHIR authentication through OAuth2/OIDC client_credentials flow. The ClientAuthInterceptor can handle Client Secret and JWT request authentication, and automatically handles authentication token requests including configuration discovery, as well as token renewal upon expiration.

Note: token refresh functionality is not in scope, as this interceptor is to be used for M2M requests.

The interceptor will use JWT authentication or Client Secret flow depending on the received ClientAuthState parameter as follows:

  1. When the ClientAuthState.keyStore property is present, the JWT flow will be performed.
  2. When the ClientAuthState.keyStore property is empty and ClientAuthState.clientSecret property is present, the Client Secret flow will be performed.

25.20.1.1Client Secret Authentication

The simplest form of client authentication uses a client ID and client secret pair. This method is suitable for confidential clients that can securely store credentials.

25.20.1.2Private Key JWT Authentication

For enhanced security, clients can authenticate using asymmetric cryptography with a private key JWT assertion. This method follows the SMART Backend Services specification.

25.20.1.2.1Security Considerations

  • Client Secret method: Ensure secrets are stored securely and transmitted only over TLS
  • Private Key JWT method: Private keys must be properly protected and rotated according to the customer's security policy
  • Both methods support additional parameters for enhanced security requirements

25.20.1.3ClientAuthInterceptor Usage

ClientAuthInterceptor interceptors must be instantiated using the fromState() static method with a ClientAuthState parameter, as shown in example below:

25.20.1.3.1ClientAuthInterceptor Instantiation Example

  ClientAuthState authState = new ClientAuthState(JWT_FLOW_CLIENT_ID)
	.withKeystore(myServerJson.getClientAuthenticationKeystoreId())
	.withScope(PATIENT_READ_SCOPE)
	.withAdditionalParameters(List.of(new BasicNameValuePair("test-additional-param-name", "test-additional-param-value")));
  ClientAuthInterceptor clientAuthInterceptor = ClientAuthInterceptor.fromState(theAuthState);

25.20.1.3.2ClientAuthState Object

The ClientAuthState object needs a valid clientId, matching the auth server Client ID definition, and at least one of the keystoreName or clientSecret properties, as shown below:

ParameterRequiredDescription
clientIdYesThe client identifier registered with the authorization server
keystoreName[1]Name of the keystore containing the signing key
clientSecret[1]The client secret provided during registration
scopeYesSpace-separated list of requested scopes
forceHttpInTokenRequestAudience [2]NoForce HTTP scheme in token endpoint audience claim

[1] One of these properties ir required

[2] When the authentication server is set behind a TLS-termination proxy, it may not accept audience urls with https protocol. Setting this parameter to true indicates forcing audience url protocol to be set to http, even when the auth server url protocol is https.