Question
· 5 hr ago

%SYS.OAuth2.AccessToken - Retrieval

I built a BP, that every time that a message is received from a BS, it executes 

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

To save time, I was thinking of just creating a BS that goes out and gets the Authorization Token every hour. However then how to do I pull that Token into the BO to ensure that the Token is included in the Request that is sent to the HS.FHIRServer.Interop.HTTPOperation?

Product version: IRIS 2025.1
$ZV: IRIS for UNIX (Red Hat Enterprise Linux 8 for x86-64) 2025.1 (Build 230_2U) Wed Jun 4 2025 18:50:44 EDT [HealthConnect:8.2.2]
Discussion (3)2
Log in or sign up to continue

To have a Business Service (BS) that retrieves and saves an authorization token for use by a Business Operation (BO), here are the steps:

  1. Create your BS to retrieve the token and store it securely, such as in a global or a data structure. For example:

    • Use ##class(%SYS.OAuth2.Authorization).GetAccessTokenClient to retrieve the token.
    • Save the retrieved token in a globally accessible location (e.g., a global or a persistent data structure).
  2. In the BO, make use of the token when firing off requests. You can use the AddAccessToken method of %SYS.OAuth2.AccessToken to attach the token directly to HTTP requests made by the BO [1][2].

  3. For implementation:

    • In the BS, schedule a process to fetch a new token periodically and refresh it if expired.
    • In the BO, retrieve the stored token from your chosen location and include it in outgoing HTTP requests.

Here’s a simple BO implementation snippet for using the stored token:

Method MakeRequest() As %Status {
    Set httpRequest = ##class(%Net.HttpRequest).%New()
    set token = <retrieve the stored token>
    $$$THROWONERROR(httpRequest.SetHeader("Authorization", "Bearer "_token))
    $$$THROWONERROR(httpRequest.Post(<Your API Endpoint>, .response))
    Quit $$$OK
}

Ensure that your logic for saving and retrieving the token handles expiration and regeneration correctly for continuity.

References: [1][2]

Sources:

Hey Scott.

The call to ##class(%SYS.OAuth2.AccessToken).IsAuthorized() will return the most recent active token (if available). So a token generated in a BS running every hour would be the same token returned when your BP makes a call to ##class(%SYS.OAuth2.AccessToken).IsAuthorized(). 

If you were to do this and still keep the code in the BP per your codeblock, you'd find that your BP would then almost never hit the condition of if 'isAuth unless the token happened to expire between the time of your next BS run and the BP attempting to use that token.

That all said, would it be much of a time save having the BS running the task every hour vs checking the validity of the token at the point of using it and then only reauthorising when it's no longer valid?