Announcement

Collapse

Mirth Connect 4.0.1 Released!

Mirth Connect 4.0.1 is now available as an appliance update and on our GitHub page. Mirth Connect 4.0.1 is a patch release containing a bug fix which includes fixing a Jetty keystore regression that caused Connect servers using a PKCS12 keystore containing a wildcard certificate and/or a certificate with a SAN to throw an exception on startup. See the release notes for the list of fixes and updates.

Download | See What's New | Upgrade Guide | Release Notes

For discussion on this release, see this thread.
See more
See less

OAuth2.0

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • OAuth2.0

    Hi

    Could anyone give me a quick guide on how to setup a channel that posts a HL7 message to a HTTPs API that uses OAuth2?

    I'm struggling with the parameters.

    Basically I have the below instructions from the supplier:

    Our API uses OAuth2.0, so to gain access, you will need to Base 64 encode your Client ID and Client Secret (CID:CSECRET), place that in the “Authorization: Basic ENCODED_DETAILS” header and post “grant_type=client_credentials” to https://someurl.com/api/auth.

    If successful, using the access token that is returned, you can post your HL7 message to

    https://someurl.com/api/hl7/refer?ac...n=ACCESS_TOKEN.

    Any help is appreciated, there isnt much out there on Mirth and OAuth2

    Thanks,
    Dave

  • #2
    Its pretty simple. The first destination would be a HTTP Sender connector, which will go to the auth end point, You can capture the token in the response transformer of this destination. Put the token in a channelMap for subsequent calls.

    You have to break down the auth call and put things at the right place..if I remember correctly, clientID and secret goes in the query parameter.
    HL7v2.7 Certified Control Specialist!

    Comment


    • #3
      At my organization we use OAuth2 using a Javascript web token JWT to communicate with Oauth2 for certain applications. That is several steps more complex but I can give you the general idea.
      NOTE: We use a 3rd party java library to construct the JWT in the transformer step. I won't go into that here as it is WAY out of the scope of the question.

      Source is on a timer/cron job and is a javascript reader. We have it return "<root>abc</root>". The real magic is in the http sender destination.
      Destination 1 is an http sender to the Oauth server.
      Query Params are
      Code:
          client_assertion:   base 64 encoded JWT header+payload+sig. 
          grant_type : client_Credentials
          client_assertion_type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer   <==== Yours will be different.
      That will return something like
      Code:
      {
         "access_token" : keyYouWantHereAsBase64,
         "token_type": "bearer",
         "expires_in": seconds-to-live eg 900,
         "scope": based on security so who knows
      }
      You need to then use a responseTransformer and pull out the access_token value and save it to a channelMap.

      Then in the second destination in the same chain....
      have the radio button for Authentication set to No.

      but In the headers have
      Authorization: Bearer ${valueOfAccessToken}


      Was this helpful?

      Comment


      • #4
        Originally posted by collinsmj View Post
        At my organization we use OAuth2 using a Javascript web token JWT to communicate with Oauth2 for certain applications. That is several steps more complex but I can give you the general idea.
        NOTE: We use a 3rd party java library to construct the JWT in the transformer step. I won't go into that here as it is WAY out of the scope of the question.

        Source is on a timer/cron job and is a javascript reader. We have it return "<root>abc</root>". The real magic is in the http sender destination.
        Destination 1 is an http sender to the Oauth server.
        Query Params are
        Code:
        client_assertion: base 64 encoded JWT header+payload+sig.
        grant_type : client_Credentials
        client_assertion_type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer <==== Yours will be different.
        That will return something like
        Code:
        {
        "access_token" : keyYouWantHereAsBase64,
        "token_type": "bearer",
        "expires_in": seconds-to-live eg 900,
        "scope": based on security so who knows
        }
        You need to then use a responseTransformer and pull out the access_token value and save it to a channelMap.

        Then in the second destination in the same chain....
        have the radio button for Authentication set to No.

        but In the headers have
        Authorization: Bearer ${valueOfAccessToken}


        Was this helpful?
        Hi, I don't suppose you've got a channel you could share with me? I'm trying to get my head round OAuth2 and JWT as it's the first time I've used it and I'm getting nowhere fast. Haven't been able to find anything of much use online.

        Comment


        • #5
          Originally posted by stevenk View Post

          Hi, I don't suppose you've got a channel you could share with me? I'm trying to get my head round OAuth2 and JWT as it's the first time I've used it and I'm getting nowhere fast. Haven't been able to find anything of much use online.
          I haven't checked back here in 2 months. Sorry for delay. Have you installed jose4j as a 3rd party class onto your mirth library? Or some similar java tool to create a jwt?

          Here is my channel's transformer

          Code:
          var encoded;
          var keySpec;
          var claims = new Packages.org.jose4j.jwt.JwtClaims();
          var jws = new Packages.org.jose4j.jws.JsonWebSignature();
          var keyFac = java.security.KeyFactory.getInstance("RSA");
          var privateKey
          
          encoded = Packages.org.apache.commons.codec.binary.Base64.de codeBase64(
          'BASE64 ENCODED PRIVATE KEY GOES HERE').PKCS8EncodedKeySpec(encoded);
          privateKey = keyFac.generatePrivate(keySpec);
          
          claims.setGeneratedJwtId();
          claims.setIssuer('string identifer unique to you');
          claims.setSubject('string identifer unique to you');
          
          
          // I time travel here in case of time server issues being off. If sever is running 20 seconds behind the
          // token in question may not be considered active yet. This saved me a lot of headaches.
          claims.setNotBeforeMinutesInThePast(1);    
          claims.setExpirationTimeMinutesInTheFuture(4);
          claims.setIssuedAtToNow();
          claims.setAudience(Oauth 2 URL endpoint);
          
          jws.setHeader('typ', 'JWT');
          jws.setKey(privateKey);
          jws.setPayload(claims.toJson());
          // there are several enum values we can use here. It depends on what the oAuth server is expecting. SHA384 is just an example
          jws.setAlgorithmHeaderValue(org.jose4j.jws.Algorit hmIdentifiers.{Select ENUM Value});
          
          
          connectorMap.put('JWT', jws.getCompactSerialization());    <=== drops the full encoded jwt string into a channel map var.

          And then when we send off for auth to the oAuth server we send there query params.
          Code:
          client_assertion : ${JWT}
          grant_type : client_credentials
          client_assertion_type : urn:ietf:params:oauth:client-assertion-type:jwt-bearer
          And for hope's sake, set Context type of the post to this value ---> application/x-www-form-urlencoded. Don't leave it as the default.

          And the oAuth server will respond with a bearer token payload. Just parse the response and you have what needs to be past to the api.



          Note: I had to post and save this one line at a time or it would get stuck saving. Very odd.
          Last edited by collinsmj; 07-08-2021, 09:44 AM.

          Comment


          • #6
            I am trying this out, I was able to add the third-party to my custom lib folder. Though when on this code step i get a red error


            HTML Code:
            jws.setAlgorithmHeaderValue(org.jose4j.jws.AlgorithmIdentifiers.{'SHA384 '});
            will this work maybe
            HTML Code:
            jws.setAlgorithmHeaderValue(org.jose4j.jws.AlgorithmIdentifiers.('{RS384}'));

            Comment


            • #7
              I get this error , maybe my base64 private key is not correct?

              Java class "[B" has no public instance field or method named "PKCS8EncodedKeySpec".

              Comment


              • #8
                I believe there is a typo, likely due to what he put in his edit note. This forum software sucks, and I recommend asking future questions in github Discussions (see link in banner across the top of this forum.) It has way better support for code sharing.

                I think it should look like this.
                Code:
                encoded = Packages.org.apache.commons.codec.binary.Base64.decodeBase64('BASE64 ENCODED PRIVATE KEY GOES HERE');
                keySpec = new Packages.java.security.spec.PKCS8EncodedKeySpec(encoded);
                privateKey = keyFac.generatePrivate(keySpec);
                P.S. I had trouble getting this to post, too.

                Comment


                • #9
                  what is best approach to store and use Private, Public Keys to make sure no body can copy them from DB (where channel code is stored) , although mirth login has been changed from default to strong one and DB is also password protected and server access is well protected using 2F authentication and secure VPN tunnel.

                  Comment


                  • #10
                    Humair , you are commenting on a 5 year old post and also "hijacking" the thread. Please read the forum etiquette at https://forums.mirthproject.io/artic...orum-etiquette.

                    So in your case bullet 4 applies. so just create new post.
                    Last edited by pacmano; 05-08-2022, 02:36 PM.
                    Diridium Technologies, Inc.
                    https://diridium.com

                    Comment

                    Working...
                    X