Authorization on Behalf of a System with JWT Authentication

184 views
Skip to first unread message

Sumanth Satheesh

unread,
Mar 29, 2023, 4:22:42 PM3/29/23
to Oracle Cerner FHIR Developers
Hello Cerner Team,

Need details  steps on how to get Authorized on behalf of System via JWT  Authentication, currently in the cerner site, information is very less  on JWT authentication

Below mentioned my details of APP creation on JWT signed token creation

we have created an application with cerner-code portal with Audience as System( for bulk data export) and product based on MILLENNIUM and have uploaded the JWK set as well( Public key)

Can anybody help me out what are the parameters( like grant type, a place holder for signed JWT) I need to pass for the token endpoint to get  authenticated via JWT, 

JWT singed token created using Rs384 and below mentioned payload for the same 
{
  "sub": "f5e29141-ee16-45af-87a5-208420fe4128",
  "iss": "f5e29141-ee16-45af-87a5-208420fe4128",
  "aud": "https://authorization.cerner.com/tenants/ec2458f2-1e24-41c8-b71b-0e701af7583d/protocols/oauth2/profiles/smart-v1/token",
  "jti": "50b1111d-29f0-0450-adcd-f2b265b8d1eb",
  "exp": 1680120280

}


Thanks 
Sumanth s

Rich Carr

unread,
Mar 31, 2023, 8:35:48 AM3/31/23
to Oracle Cerner FHIR Developers
You take your clientid and secret, and convert them to a base64string, put that in the header as bearer.  grant_type is client_credentials, and you have to include a scope parm, like Patient_read

Here is my method in C#

     public static async Task<string> getCernerToken(string scope)
        {
            if (string.IsNullOrEmpty(ClientId))
                return "Missing ClientID";

            if (string.IsNullOrEmpty(TenantId))
                return "Missing TenantID";

            if (string.IsNullOrEmpty(Secret))
                return "Missing Secret";

            if (string.IsNullOrEmpty(BaseAuthUrl))
                return "Missing BaseAuth";

            var token = string.Empty;
            var clientSecretString = $"{ClientId}:{Secret}";
            var convertedString = Convert.ToBase64String(Encoding.ASCII.GetBytes(clientSecretString));

            var authUrl = $"{BaseAuthUrl}{TenantId}/protocols/oauth2/profiles/smart-v1/token";
            var grantType = "client_credentials";

            HttpResponseMessage res = new HttpResponseMessage();

            using (var client = new HttpClient())
            {
                var builder = new UriBuilder(authUrl);
                var url = builder.ToString();

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", convertedString);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                // Fiddler or Wireshark

                var data = new FormUrlEncodedContent(new Dictionary<string, string> { { "grant_type", grantType }, { "scope", scope } });

                res = await client.PostAsync(authUrl, data);
            }
            var responseString = await res.Content.ReadAsStringAsync();

            if (string.IsNullOrEmpty(responseString))
                return string.Empty;

            var json = JObject.Parse(responseString);

            if (json != null)
                token = json["access_token"]?.ToString();

            if (token == null)
                token = string.Empty;

            return token;
        }

Sumanth Satheesh

unread,
Mar 31, 2023, 1:37:11 PM3/31/23
to Oracle Cerner FHIR Developers
Hello Team,

Thanks for the reply, but the above C# method is getting authenticated via BasicAuth, In my case need to achieve JWT Authentication, where I need to send a signed JWT token to the Cerner  Token URL endpoint and then get the access Token for further request.

Any Help on JWT-based Authentication will be much appreciated.

Thanks'
Sumanth S

Rich Carr

unread,
Mar 31, 2023, 2:05:49 PM3/31/23
to Oracle Cerner FHIR Developers
This is the next call to actually get data or add or update - note the code I pasted above is called at the top and then sent in as a Bearer token

using (var client = new HttpClient())
                {
                    var scope = $"system/{fhirDataType}.read";

                    cernerToken = getCernerToken(scope).Result;
                    query = query.Replace(";", "&");
                    var fhirServerUrl = R4BaseUrl + TenantId;

                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", cernerToken);
                    client.DefaultRequestHeaders.Add("Accept", "application/fhir+json");

                    var builder = new UriBuilder(fhirServerUrl + "/" +  fhirDataType + query);
                    var url = builder.ToString();

                    // Foritfy CWE-918.
                    if (!IsValidURI(url))
                        throw new Exception("Invalid Uri passed.");

                    res = await client.GetAsync(url);
                }

                return await res.Content.ReadAsStringAsync();
Reply all
Reply to author
Forward
0 new messages