Skip to content

Instantly share code, notes, and snippets.

@mygzi
Created August 10, 2022 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mygzi/8633044f86e0610824963cdc59ac5d1c to your computer and use it in GitHub Desktop.
Save mygzi/8633044f86e0610824963cdc59ac5d1c to your computer and use it in GitHub Desktop.
Epic on FHIR backend system (sandbox) authentication sample
from datetime import datetime
from datetime import timezone
from datetime import timedelta
import requests
import jwt
import os
import uuid
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.x509 import load_pem_x509_certificate
# load key pair created by following https://fhir.epic.com/Documentation?docId=oauth2&section=Creating-Key-Pair
os.chdir('replace-with-path-to-key-files')
with open('epic-on-fhir-private-key.pem', 'rb') as private_key_file:
lines = private_key_file.read()
private_key = load_pem_private_key(lines, None, default_backend())
with open('epic-on-fhir-public-key-509.pem', 'rb') as cert_file:
cert_str = cert_file.read()
cert_obj = load_pem_x509_certificate(cert_str)
public_key = cert_obj.public_key()
# build the JWT
algorithm = "RS384"
client_id = "replace-with-non-production-client-id-from-epic-app-listing"
endpoint = "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token"
payload = {
"iss": client_id,
"sub": client_id,
"aud": endpoint,
"jti": str(uuid.uuid4()),
"exp": datetime.now(tz=timezone.utc) + timedelta(minutes=+1),
}
token = jwt.encode(
payload,
private_key,
algorithm=algorithm,
headers={"alg": "RS384", "typ": "JWT"},
)
print(f"headers {jwt.get_unverified_header(token)}")
decoded = jwt.decode(token, public_key, audience=endpoint, algorithms=[algorithm])
print(f"payload {decoded}")
payload = {
"grant_type": "client_credentials",
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
"client_assertion": token
}
r = requests.post('https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token', data=payload)
print(r.status_code) # is everything 200 OK?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment