Question Shane M Elliott · Apr 28

FHIR Server OAUTH2 with Microsoft Entra Intersystems Health 2025.3

I am working on setting up OAUTH with FHIR and Microsoft Entra.  I have configured the Client and configured it in the FHIR Server successfully. However, I get 401 when authenticating with a token.   Looking at ^ISCLOG I see:
^ISCLOG("Data",9,0)="accessToken=<jwt token>, scope=, aud="
^ISCLOG("Data",10)=$lb(3,"OAuth2","[OAuth2.ServerDefinition:ValidateJWT]","171430","%SYS","2026-04-28 17:41:25.305549397","OAuth2.ServerDefinition.1","","zwKKakZZZx2")
^ISCLOG("Data",10,0)="JWT valid? sc=1"
^ISCLOG("Data",11)=$lb(3,"HSFHIRServer","[HS.FHIRServer.RestHandler:OnPreDispatch]CSP Request","171430","HEALTHSHARE","2026-04-28 17:41:25.30613001","HS.FHIRServer.RestHandler.1","","zwKKakZZZx2")
^ISCLOG("Data",11,0)="Content-Type: , Secure: 1, $Username: UnknownUser"
Any Suggestions on what the issue might be? 

Product version: IRIS 2025.3
$ZV: IRIS for UNIX (Ubuntu Server LTS for x86-64 Containers) 2025.3 (Build 226U) Thu Nov 13 2025 12:39:27

Comments

Shane M Elliott · Apr 28

Update:  I enabled OAuth globally and now I can get a user, create a user and assign scopes.  But I still get 401.  

0
David Hockenbroch · Apr 29

What I've found a written about here may be relevant, but I'm  not sure how to address that issue in your specific use case.

0
Shane M Elliott  Apr 30 to David Hockenbroch

I have identified my issue, and implemented a workaround at least for my proof of concept.  What I found in the FHIR Logs is the audience (aud) is not matching from the FHIR Oauth class.   It appears the OAuthClass is blocking based on the audience as Entra is sending the clientID and the FHIR OAuth Class is expecting something different (my guess is endpoint?).  For now, I have implemented a custom interactionStrategy and a custom OAuth2Token Handler Class to replace the standard one so this audience block does not happen.  I am pending Support on this issue otherwise.  
^FSLOG(24110)="ValidateToken^HS.FHIRServer.Util.OAuth2Token^170903|Msg|ValidateJWT() token aud=<Entra Client ID> |04/29/2026 12:27:34.436871PM"

^FSLOG(24111)="ValidateToken^HS.FHIRServer.Util.OAuth2Token^170903|Msg|Token aud failed validation|04/29/2026 12:27:34.436896PM"

0
Shane M Elliott  Apr 30 to Shane M Elliott

yes, I was correct,. it is expecting the baseUrl
 

Method ValidateAudience() As %Boolean [ Private ]
{
    Set JWTAudience = ..%TokenObject.aud
   
    If JWTAudience'="" {
        Set matched = 0
        Set currentAud = $$formatAud(..%BaseURL)
        If '$IsObject(JWTAudience) {
            // Compare single audience from JWT.
            If $$formatAud(JWTAudience)=currentAud {
                Set matched = 1
            }
        } Else {
            // Compare multiple audience from JWT. In this case it is a %DynamicArray.
            For i = 0:1:JWTAudience.%Size()-1 {
                If $$formatAud(JWTAudience.%Get(i))=currentAud {
                    Set matched = 1
                    Quit
                }
            }
        }
0
Tani Frankel  May 3 to Shane M Elliott

See this latest post re a new feature coming in 2026.2 that addresses your exact issue.

If you want you can give it a try with the Developer Preview version (note this is not supported for production use of course, just for your own internal testing; and share any feedback you might have, that's why it's out there).

0