Question
· Nov 25, 2022

From an INTEGRATION Environment connect to a PREPRODUCTION Environment to access the JWT Token Validating Resource Server.

Good morning,

We have been investigating how to activate a Server to Generate Tokens and an associated Resource Server to Validate the Token. This step, actually we have found out with the invaluable support of @Alberto Fuentes from Intersystems.

Then the need is as follows: To centralize in 1 single Environment ( PREPRODUCTION ) and in 1 single Namespace the Resource Server ( for example in a dedicated NAMESPACE called AUTHSERVER ) ; we would need somehow to "call", "invoke", "communicate" from the other environments ( for example INTEGRATION ) with the PREPRODUCTION Resource Server in order to Validate the Token. Please, could you guide, teach or instruct us in this regard?

📍 What is the way to "call", "invoke", "communicate" from the other environments ( for example INTEGRATION ) with the PREPRODUCTION Resource Server in order to Validate the Token?

Specifically, we have in Integracion a REST Service called "Servicios.REST.Radiologia.CConcertadosv01r00", and inside a method called "ResServer". Our research has led us to delve into the following code:

ClassMethod ResServer(accessToken As %String(MAXLEN="")) As %Status
{
$$$LOGINFO("Entra en método ResServer")
    // This is a dummy resource server which just gets the access token from the request
    // and uses the introspection endpoint to ensure that the access token is valid.
    // Normally the response would not be security related, but would contain some interesting
    // data based on the request parameters.
    
    // retrieve access token from HTTP request
    ;set accessToken = ##class(%SYS.OAuth2.AccessToken).GetAccessTokenFromRequest(.status) /*
    if $$$ISERR(status) {
        set %response.Status = ..#HTTP401UNAUTHORIZED
        write "[Error] GetAccessTokenFromRequest: "_$system.Status.GetErrorText(status),!
        quit $$$OK
    }
    */ $$$LOGALERT("Antes de set isJWTValid = ##class(%SYS.OAuth2.Validation).ValidateJWT('resserver',accessToken,'','',.jwtPayload ,.securityParameters,.sc)")
    // validate token
    ;set isJWTValid = ##class(%SYS.OAuth2.Validation).ValidateJWT("resserver",accessToken,"","",.jwtPayload ,.securityParameters,.sc)
    set isJWTValid = ##class(%SYS.OAuth2.Validation).ValidateJWT("https://[Servidor de PRE]:57773/resserver/",accessToken,"","",.jwtPayload ,.securityParameters,.sc)
    $$$LOGALERT("Despues de isJWTValid ... apuntando a https://[Servidor de PRE]:57773/resserver/")
            
    $$$LOGINFO("Antes de if (('isJWTValid) || ($$$ISERR(sc))) {")
    $$$LOGINFO("Imprimir ('isJWTValid): "_('isJWTValid))
    $$$LOGINFO("Imprimir ($$$ISERR(sc): "_($$$ISERR(sc)))
    $$$LOGINFO("Imprimir $system.Status.GetErrorText(sc): "_$system.Status.GetErrorText(sc))
    if (('isJWTValid) || ($$$ISERR(sc))) {
    /*
        set %response.Status = ..#HTTP401UNAUTHORIZED
        write "Error Getting Access Token="_$system.Status.GetErrorText(sc),!
        */
        quit '$$$OK
    } $$$LOGINFO("Antes de set sc = ##class(%SYS.OAuth2.AccessToken).GetIntrospection('resserver', accessToken, .jsonObject)")
    // introspection
    set sc = ##class(%SYS.OAuth2.AccessToken).GetIntrospection("resserver", accessToken, .jsonObject)
    if $$$ISERR(sc) {
    /*
        set %response.Status = ..#HTTP401UNAUTHORIZED
        write "Introspection Error="_..EscapeHTML($system.Status.GetErrorText(sc)),!
        */
        quit '$$$OK
    }
    
$$$LOGINFO("Antes de write 'OAuth 2.0 access token used to authorize resource server (RFC 6749)<br>'")
/*
    write "OAuth 2.0 access token used to authorize resource server (RFC 6749)<br>"
    write "Access token validated using introspection endpoint (RFC 7662)<br>"
    write " scope='"_jsonObject.scope_"'<br>"
    write " user='"_jsonObject.username_"'",!
    */
    
    $$$LOGINFO("Antes del final quit $$$OK")
    quit $$$OK
}

Next our inquiries lead us to:

This line if calls from PREPRODUCTION to the PREPRODUCTION Resource Server and Validates the Token correctly:

set isJWTValid = ##class(%SYS.OAuth2.Validation).ValidateJWT("resserver",accessToken,"","",.jwtPayload ,.securityParameters,.sc)

However, if we try to invoke from INTEGRATION to the PREPRODUCTION Resource Server qualifying the first parameter, the "client" with the complete Address of the PRE Resource Server; it gives Exception:

set isJWTValid = ##class(%SYS.OAuth2.Validation).ValidateJWT("https://[DNS de PRE]:57773/resserver/",accessToken,"","",.jwtPayload ,.securityParameters,.sc)

In particular the Exception we observe in the LOGS of the REST Service is:

ERROR #5002: Error de cache: <UNDEFINED>zValidateJWT+22^%SYS.OAuth2.Validation.1 *client

Which seems to be due to the fact that in the internal function of the class:"%SYS.OAuth2.Validation" titled: "ValidateJWT" ; in the call "Set client=##class(OAuth2.Client).Open(applicationName,.sc)

 

An Exception is generated based on the fact that it costs to open the Resource Server; in the class: OAuth2.Client in the Open method on the line Set client=##class(OAuth2.Client).%OpenId(applicationName,,.sc)

Please, could you guide, teach or instruct us in this regard?

📍 The question is what way is there to "call", "invoke", "communicate" from the other environments ( for example INTEGRATION ) with the PREPRODUCTION Resource Server in order to Validate the Token?

 

Thank you very much in advance for your time, support and help.

 

 

Best regards

Discussion (1)1
Log in or sign up to continue

🧐 Additionally we have read 💭💭 carefully:

https://docs.intersystems.com/healthconnectlatest/csp/docbook/DocBook.UI...

https://docs.intersystems.com/healthconnectlatest/csp/docbook/DocBook.UI...

https://docs.intersystems.com/healthconnectlatest/csp/docbook/DocBook.UI...

https://docs.intersystems.com/healthconnectlatest/csp/docbook/DocBook.UI...

https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI...

https://community.intersystems.com/post/making-jwtoauth20

However, we do still have the same question:

What way is there to "call", "invoke", "communicate" from the other environments ( for example INTEGRATION ) with the PREPRODUCTION Resource Server in order to Validate the Token?

That is to say, the question in another way would be:

What mechanism exists to communicate from an Environment A (Integration) with an Environment B (Preproduction) with the mission to Validate the Token from Environment A using the centralized Resource Server available in Environment B?

👀 Thank you very much for your attention, and thank you for your answers.

Best regards