Pull oauth2 token from ib_reply

Homepage Clovertech Forums Cloverleaf Pull oauth2 token from ib_reply

  • Creator
    Topic
  • #119915
    Bill Pitts
    Participant

    Hi,

    REST API using java/ws-rawclient outbound.

    Need to send GET request to retrieve oauth2 token, then plug that token into https header {Bearer token} on outbound POST msg with HL7 payload.  Token can also expire so I need to evaluate token from response and re-issue token request if expired.

    Have the GET working, see the encrypted token in the header of ib-reply but can’t seem to extract it from the USERDATA.  Have tried “keylget” and “string first” [looking for “token”] in userdata but not getting token value returned.

    Output from Clover (19.1.1) logfile below:

    Suggestions appreciated.  Thanks!

     

    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:08/31/2022 16:04:24] org.apache.cxf.interceptor.LoggingOutInterceptor:INFO: Outbound Message
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] —————————
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] ID: 3
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Address: https://masshiway-services-cert.hhs.state.ma.us/HHS/API/jwt/gettoken?scope=SyndromicAPIService&id=123
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Http-Method: GET
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Content-Type:
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Headers: {Authorization=[Basic VFVGVFNNRURDRVJUOiRIbDchZWUkdXJucSM4MDA=], Accept=[*/*]}
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Payload: MSH|^~\&||… …OBX|7|TX|10182-4^History of travel Narrative^LN|7|No||||||F
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] ————————————–

    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:08/31/2022 16:04:24] org.apache.cxf.interceptor.LoggingInInterceptor:INFO: Inbound Message
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] —————————-
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] ID: 3
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Response-Code: 200
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Encoding: ISO-8859-1
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Content-Type: application/soap+xml;
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] Headers: {connection=[keep-alive], content-type=[application/soap+xml;], Date=[Wed, 31 Aug 2022 20:04:24 GMT], Keep-Alive=[timeout=75], Server=[], token=[eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJEUFY2MDEiLCJleHAiOjE2NjE5NzY1NjQuNzIsImF0b21pY3JvbGVfbW9kdWxlIjoiNDQzL0hIUy9BUEkvc2VydmljZS9ITDcvU3luZHJvbWljIiwiY2xpZW50X2lkIjoiVFVGVFNNRURDRVJUIn0.VQK2YD1zkCAConfjaXxnbTr3NwY-5GvVM8aanDMuHoCbm6KJcyORditQgA7edpEVawwMEh7TXEzxPvswmY3khYJX8Oh9Yh0aGjwSyuV2woBJNypv60saYv9YjNhdh2wAEZrD-myV9qTN4UVj-woNtj8Cr-eEHwDvW7DQgPjoMcc_jSkYI5-RteDubjqSs0HBrCT1fttDeIzHrQ5mO8gukUiXaleQhXu3Sc87eXO_OEvYD2rDMpDXQ4GwViSnukVL_-YLD3pCo_vfBkm-RLTbQfbrlNsV9tJ6mGqQzTQfhp-oByZ1dy5SkdXMBvzQ0M7ftCGuM_Z-wwZ-WjnEQsfgBQ], transfer-encoding=[chunked], X-Backside-Transport=[OK OK,FAIL FAIL], X-Global-Transaction-ID=[23056659630fbec8165abce1]}
    [java:java:INFO/1:MDPH_Syndromic_REST_API_0:–/–/—- –:–:–] ————————————–

    [tcl :out :INFO/0:MDPH_Syndromic_REST_API:08/31/2022 16:04:24] userdata = {httpResponseInfo OK} {httpResponseHeaders {{Keep-Alive timeout=75} {transfer-encoding chunked} {Server {}} {X-Backside-Transport OK\ OK,FAIL\ FAIL} {connection keep-alive} {content-type application/soap+xml\;} {X-Global-Transaction-ID 23056659630fbec8165abce1} {Date Wed,\ 31\ Aug\ 2022\ 20:04:24\ GMT} {token eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJEUFY2MDEiLCJleHAiOjE2NjE5NzY1NjQuNzIsImF0b21pY3JvbGVfbW9kdWxlIjoiNDQzL0hIUy9BUEkvc2VydmljZS9ITDcvU3luZHJvbWljIiwiY2xpZW50X2lkIjoiVFVGVFNNRURDRVJUIn0.VQK2YD1zkCAConfjaXxnbTr3NwY-5GvVM8aanDMuHoCbm6KJcyORditQgA7edpEVawwMEh7TXEzxPvswmY3khYJX8Oh9Yh0aGjwSyuV2woBJNypv60saYv9YjNhdh2wAEZrD-myV9qTN4UVj-woNtj8Cr-eEHwDvW7DQgPjoMcc_jSkYI5-RteDubjqSs0HBrCT1fttDeIzHrQ5mO8gukUiXaleQhXu3Sc87eXO_OEvYD2rDMpDXQ4GwViSnukVL_-YLD3pCo_vfBkm-RLTbQfbrlNsV9tJ6mGqQzTQfhp-oByZ1dy5SkdXMBvzQ0M7ftCGuM_Z-wwZ-WjnEQsfgBQ}}} {httpResponseCode 200}
    [tcl :out :INFO/0:MDPH_Syndromic_REST_API:08/31/2022 16:04:24] responseCd = httpResponseCode 200

    [xlt :rout:ERR /0:oauth2_Test_xlate:08/31/2022 16:04:24] [0.0.422980] No reply route defined for trxid ” and destination ‘2_x_Syndromic_CrossSite’. Please define a route with ‘2_x_Syndromic_CrossSite’ as one of its destinations in “Route Replies”
    Engine idle — 08/31/2022 16:04:34

Viewing 7 reply threads
  • Author
    Replies
    • #119916
      Charlie Bursell
      Participant

      Not sure its a keyed list.  Try to echo the USERDATA separately with a few LF before and after to make it stand out.  You try something like :  In an IB Reply proc.

      Assume USERDATA is in variable myuser
      set myuser [msgmetaget $mh USERDATA]

      foreach ky [keylkeys myuser] {echo KEY: $ky  DATA: [keylget myuser $ky]}

    • #119922
      Don Martin
      Participant

      Your token should be retrievable from the USERDATA keyed list.  It looks like you’re getting this keyed list back:

      userdata = {httpResponseInfo OK} {httpResponseHeaders {{Keep-Alive timeout=75} {transfer-encoding chunked} {Server {}} {X-Backside-Transport OK\ OK,FAIL\ FAIL} {connection keep-alive} {content-type application/soap+xml\;} {X-Global-Transaction-ID 23056659630fbec8165abce1} {Date Wed,\ 31\ Aug\ 2022\ 20:04:24\ GMT} {token eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJEUFY2MDEiLCJleHAiOjE2NjE5NzY1NjQuNzIsImF0b21pY3JvbGVfbW9kdWxlIjoiNDQzL0hIUy9BUEkvc2VydmljZS9ITDcvU3luZHJvbWljIiwiY2xpZW50X2lkIjoiVFVGVFNNRURDRVJUIn0.VQK2YD1zkCAConfjaXxnbTr3NwY-5GvVM8aanDMuHoCbm6KJcyORditQgA7edpEVawwMEh7TXEzxPvswmY3khYJX8Oh9Yh0aGjwSyuV2woBJNypv60saYv9YjNhdh2wAEZrD-myV9qTN4UVj-woNtj8Cr-eEHwDvW7DQgPjoMcc_jSkYI5-RteDubjqSs0HBrCT1fttDeIzHrQ5mO8gukUiXaleQhXu3Sc87eXO_OEvYD2rDMpDXQ4GwViSnukVL_-YLD3pCo_vfBkm-RLTbQfbrlNsV9tJ6mGqQzTQfhp-oByZ1dy5SkdXMBvzQ0M7ftCGuM_Z-wwZ-WjnEQsfgBQ}}} {httpResponseCode 200}

       

      This matches what the clover docs says about the format of USERDATA for web service calls.  Here’s an example of the USERDATA keyed list for an outbound ws call:

      {httpRequestHeaders {{Accept */*} {Cache-Control no-cache} {connection keep-alive} {Content-Length 1392} {content-type {application/soap+xml; charset=UTF-8}} {Host localhost:9003} {Pragma no-cache} {User-Agent {Apache CXF 2.4.2}}}} {httpRequestInfo {{method POST} {requestURL http://localhost:9003/xdsregistryb} {path /xdsregistryb}}}

      So, to get the token in your ib reply, you would first get the USERDATA keyed list, then get the httpResponseHeaders keyed list, then get the token.  You can’t use keylget to directly get token without first working your way into the nested list.

       

      Also, I see you have an error about no reply route defined for your ws call.  Not sure if that is just a benign issue for you or not.  We typically set up a reply route and extract the access token with some tcl code in the reply route.

       

    • #119924
      Bill Pitts
      Participant

      USERDATA was keyed list;    was able to get the token by “drilling” down through the nested list,  per @don-martinsanfordhealth-org suggestion.  I had been trying to access token directly from the USERDATA keyed list

      “So, to get the token in your ib reply, you would first get the USERDATA keyed list, then get the httpResponseHeaders keyed list, then get the token.  You can’t use keylget to directly get token without first working your way into the nested list.”

      … then I decoded the token so that I can check the expiration time (“exp” from below):

      DecodedToken = DECODE {“alg”:”RS256″}{“iss”:”DPV601″,”exp”:1662054993.705,”atomicrole_module”:”443/HHS/API/../../..”,”client_id”:”….”}

      Thanks … more to follow!

    • #119944
      Bill Pitts
      Participant

      Update:

      I’m able to send the GET request to the TOKEN endpoint,   pull the token out of the https reply and evaluate token expiration time but stuck at this point.

      Need to put the token in the header for subsequent POST request.

      Not sure how to: 1) put the token I’ve isolated into the  header ;   2) generate the POST msg once the token has been received from the response to the original GET token request

      Config setup of thread is attached

      As always, thanks for any feedback

      Attachments:
      You must be logged in to view attached files.
    • #120337
      Rob Lindsey
      Participant

      I am trying to figure out an inbound web service using oauth2.  The outbound seems easier to do but that is just the way my brain is working right now.  Has anyone on this thread figured out the best way to do an inbound thread that checks the token provided by oauth2?

      Thanks in advance

      Rob Lindsey

    • #120424
      Bill Pitts
      Participant

      Update – reinvestigating this as we got sidetracked.

      Current status:

      Syndromic data passing to state endpoint via outbound java/ws-rawclient thread. Two conduits defined on thread – 1) to state hl7 api svc  & 2) to state api token service

      Two RawConsumers defined on thread:   1) POST_API  & 2) TOKEN_REQ

      Thread outbound tab, pre-write Proc:   tclproc to send GET request to TOKEN_REQ consumer.

      On TPSinboundReply:  separate tclproc to evaluate https reponse, pull token out of response headers, evaluate token expiration

      Here’s where I’m stuck.

      Unable to take token and put in in header for subsequent POST request to POST_API consumer and endpoint

      The message data does not seem available at that point. Just have the response data; response data just sending token, no message data.

      Would like to avoid using two outbound threads if possible.

      Thinking I may need to store token in local file and modify GET tclproc to check the token value first, then building conditional logic to branch to GET or POST request.

      Open to other suggestions.  Feel I’m missing something

       

    • #120444
      Rob Lindsey
      Participant

      Hello Bill,

      I have been able to figure out how to get oauth2 inbound token working on our world but your mileage may vary.  Below is some code that I use to check a oauth2 Token from Ping Federal.  Basically your code has to take the RequestHeaders from the USERDATA that the java ws process sends the inbound data to.  On the inbound tab the code below is the first one on the tclproc list.  From the way I understand things the code only has to check if the access token has expired and is the one your are expecting.  Again your world may be different.
      <pre># get the x-Access-Token out of the Request Headers
      set RecievedToken [keylget RequestHeaders “x-Access-Token”]
      if { $debug } { puts “$module x-Access-Token: $Recieved” }

      set BadToken 0 ; set period “.”

      set tokenList [split ${RecievedToken} $period]
      set UserTokenInfoEncoded [lindex ${tokenList} 1]
      if { $debug } { puts “$module UserTokenInfoEncoded –> $UserTokenInfoEncoded” }

      set UserTokenInfoDecoded [base64::decode ${UserTokenInfoEncoded}]
      if { $debug } { puts “$module UserTokenInfoDecoded –> $UserTokenInfoDecoded” }
      set UserTokenDict [json::json2dict $UserTokenInfoDecoded]

      if { ![string is list $UserTokenDict] || ( [llength $UserTokenDict] & 1 ) } {
      set BadToken 1
      }

      set TokenScope [dict get $UserTokenDict scope]
      set TokenClientId [dict get $UserTokenDict client_id]
      set TokenExpiry [dict get $UserTokenDict exp]

      if { $debug } {
      puts “$module TokenScope –> $TokenScope\n$module TokenClientId –> $TokenClientId\n$module TokenExpiry –> $TokenExpiry”
      }

      set Now [getclock]
      if { ${Now} < ${TokenExpiry} } {
      set BadToken 0 ;# the Token has not expired
      puts “$module $TokenClientId token has not expired”
      } else {
      set BadToken 1
      puts “$module $TokenClientId token has EXPIRED”
      }

      if { [lsearch -exact $AllowedClientList $TokenClientId] == -1 } {
      set BadToken 1 ;# the client in the Access Token is not expected on this thread
      puts “$module $TokenClientId is not expected on this interface as it is not in the ARGS list sent in”
      }

      off line info:

      robert . m . lindsey at questdiagnostics . com</pre>
      remove spaces and replace at with the proper characters.

      Rob

    • #120700
      Jim Vilbrandt
      Participant

      Hi Bill,

      Have you gotten any further with your OAUTH2 development? I need to implement an outbound REST interface with JSON Web Tokens and don’t want to reinvent the wheel.

      It would be great if someone could upload the configuration details (Box?) containing both a receiving (Server) and sending (Client) threads for testing purposes.

      Best regards from Germany! Jim Vilbrandt

Viewing 7 reply threads
  • You must be logged in to reply to this topic.

Forum Statistics

Registered Users
5,126
Forums
28
Topics
9,296
Replies
34,439
Topic Tags
287
Empty Topic Tags
10