Question
· Apr 21, 2021

First REST Operation - Custom Header

I have a vendor that is sending an HL7 message. But when I asked for more detail about their mapping tables, they told me they typically don't supply that but supply an API for customers to call so they don't have to define tables and it is more dynamic.

So with that being said I am creating my first REST operation. I understand the gist of how a REST operation works in working with other types out Non HL7 Operations (SOAP, SQL) before. You send a request and get a response back, that part I understand.

What I am not comprehending is how secure it can be if they only give you an ID, and a Secret pass code to work with.

How secure is it if they are not requiring a Certificate, or Credentials?

  • I have created a simple client TLS configuration for this Operation, I am just not sure how secure it is, and how to send a custom header within the call.

If the ID and Secret pass code has to be sent in the header, how does one create a Custom Header for authentication with the API?  

This is what I have to pass to them for Authentication...

{
"Key" : "xxxxxxxxxxxxxxxxxxxxxxxx",
"Id": "xxxxx",
"Secret": "xxxxx",
"Resource": "xxxxx",
"Instance" : "xxxxx"
}

Forgive me but I am just not finding the right documentation to point me in the direction I am looking for.

Product version: Ensemble 2018.1
$ZV: Cache for UNIX (IBM AIX for System Power System-64) 2018.1.3 (Build 414U) Mon Oct 28 2019 11:24:02 EDT
Discussion (14)2
Log in or sign up to continue

This snippet uses the built-in OAuth client to request a token and then add it to the HTTP header.

You'll need to configure an entry for the OAuth server with a sub-entry for this specific client:
https://docs.intersystems.com/healthconnectlatest/csp/docbook/Doc.View.c...

In the case of the sample code below, the client I configured is named TestClientA.

    set isAuth=##class(%SYS.OAuth2.AccessToken).IsAuthorized("TestClientA",,"*",.accessToken,.idtoken,.responseProperties,.error)

    $$$TRACE("isAuth:"_isAuth)

    if 'isAuth {
        set tSC=##class(%SYS.OAuth2.Authorization).GetAccessTokenClient("TestClientA", "*",, .error)        
        set isAuth=##class(%SYS.OAuth2.AccessToken).IsAuthorized("TestClientA",,"*",.accessToken,.idtoken,.responseProperties,.error)

        $$$TRACE("isAuth2:"_isAuth)
        
        if 'isAuth {
            quit $$$ERROR(5001,"Problem authenticating")
        }
    }

    $$$TRACE("access_token: "_accessToken)
    $$$TRACE("expires_in: "_responseProperties("expires_in"))
    $$$TRACE("scope: "_responseProperties("scope"))
    $$$TRACE("token_type: "_responseProperties("token_type"))
    
    s tSC=pRequest.HTTPHeaders.SetAt("Bearer "_accessToken,"Authorization")

Here's a cheat sheet I put together on creating an OAuth client definition:

Go to System Administration >> Security >> OAuth 2.0 >> Client

Choose “Create Server Description”

Enter the endpoint URL provided for the OAuth server and select the TLS config you created for the OAuth server. Click “Discover and Save”. It should populate details about the OAuth server.

After saving, a new server entry will appear. Click “Client Configurations” and then “Create Client Configuration”

Enter the name details, select the TLS config, and choose Client Credentials as the grant type. The redirect URL won’t actually be used, but you’ll need to enter something for hostname anyway.

Keep track of what you enter for “Application Name”. You’ll need to put this in your custom code.

Switch to the “Client Credentials” tab and enter the Client ID and Client Secret you were given.

You can definitely do the OAuth requests using basic HTTP calls.

Doing it in OnInit won't work because the token you receive has an expiration time.

You'll need to:
- For every message your Operation receives you'll need to check if the cached token's expiration time has passed (or if there's no cached token).
- If you need a new token, do your POST call to get a new token and cache it.