%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?
Comments
To have a Business Service (BS) that retrieves and saves an authorization token for use by a Business Operation (BO), here are the steps:
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).GetAccessTokenClientto retrieve the token. - Save the retrieved token in a globally accessible location (e.g., a global or a persistent data structure).
- Use
In the BO, make use of the token when firing off requests. You can use the
AddAccessTokenmethod of%SYS.OAuth2.AccessTokento attach the token directly to HTTP requests made by the BO [1][2].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.
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?
Yeah, I see your point. Thanks for your input.