Module: Multiwoven::Integrations::Core::OauthClientCredentials

Included in:
Destination::Http::Client, Source::EpicFhir::Client, Source::Http::Client
Defined in:
lib/multiwoven/integrations/core/oauth_client_credentials.rb

Overview

Shared OAuth2 client_credentials flows. Include in a connector client to:

* inject `Authorization: Bearer <token>` when connection_config[:auth_type]
is `oauth_client_credentials` or `oauth_private_key_jwt`
* cache the token in the connector's `configuration` JSON and refresh it
shortly before expiry

oauth_client_credentials — classic client_id + client_secret. oauth_private_key_jwt — client_assertion JWT signed with an RSA private key (Epic Backend Services / SMART confidential asymmetric).

The including class is expected to set @connector_instance (an object responding to configuration and update!) before making requests that should benefit from the cache. Without it, a fresh token is fetched every call — safe but wasteful.

Constant Summary collapse

AUTH_TYPE_OAUTH_CLIENT_CREDENTIALS =
"oauth_client_credentials"
AUTH_TYPE_PRIVATE_KEY_JWT =
"oauth_private_key_jwt"
OAUTH_AUTH_TYPES =
[AUTH_TYPE_OAUTH_CLIENT_CREDENTIALS, AUTH_TYPE_PRIVATE_KEY_JWT].freeze
CLIENT_ASSERTION_TYPE =
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
DEFAULT_JWT_ALGORITHM =

Epic / SMART Backend Services require RS384; RS256 is kept for other IdPs.

"RS384"
ALLOWED_JWT_ALGORITHMS =
%w[RS384 RS256].freeze
JWT_ASSERTION_LIFETIME_SECONDS =
300
TOKEN_EXPIRY_BUFFER_SECONDS =

Refresh access tokens this many seconds before their advertised expiry, so a token that expires mid-request doesn't leave the connector.

300

Instance Method Summary collapse

Instance Method Details

#build_headers(connection_config) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/multiwoven/integrations/core/oauth_client_credentials.rb', line 37

def build_headers(connection_config)
  headers = (connection_config[:headers] || {}).to_h.dup
  return headers unless oauth_auth_type?(connection_config[:auth_type])

  headers["Authorization"] = "Bearer #{ensure_oauth_token(connection_config)}"
  headers
end

#ensure_oauth_token(connection_config) ⇒ Object



45
46
47
48
49
50
# File 'lib/multiwoven/integrations/core/oauth_client_credentials.rb', line 45

def ensure_oauth_token(connection_config)
  cached = cached_oauth_token
  return cached if cached

  fetch_and_cache_oauth_token(connection_config)
end