Question
Yone Moreno · 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

0
0 194
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