1

We're automating our test with karate framework. In one of our features we need to decode a token and get a scope in the response. Everything works well, except this code in js.

function(token) {
    return JSON.parse(new Buffer(token.split('.')[1],'base64').toString('ascii')).scope;
}

Error:

Caused by: <eval>:2 ReferenceError: "Buffer" is not defined
Caused by: jdk.nashorn.internal.runtime.ECMAException

In official tutorials it is said that javascript is 'native' to karate, so we don't understand why Buffer is not recognized? What we should do? Thanks for any help

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
cygne
  • 527
  • 1
  • 10
  • 28

3 Answers3

2

I was able to successfully base64Decode a JWT token payload to JSON using the following code without the need for a Java method:

  Background:
    * def parseJwt =
  """
  function(token) {
      var base64Url = token.split('.')[1];
      var base64Str = base64Url.replace(/-/g, '+').replace(/_/g, '/');
      var Base64 = Java.type('java.util.Base64');
      var decoded = Base64.getDecoder().decode(base64Str);
      var String = Java.type('java.lang.String')
      return new String(decoded)
  };
  """

  Scenario: JWT Token
    Given path  'jwt/authenticate'
    And header x-goog-authenticated-user-email = 'email'
    And request {}
    When method get
    Then status 200
    * json result = parseJwt(responseHeaders['Set-Cookie'][0])
    * match result == {permissions: [1,2,3], iss: "us", exp: "#number", email: "email"}

Note: It does seem to be required to use json rather than def as Karate does better if it parses the string to json itself. Also, you may obtain the token from a header rather than a cookie as in this example if so, just change the responseHeader that you are looking for.

Loren
  • 9,783
  • 4
  • 39
  • 49
  • thanks ! is there an online / public JWT example and I would like to add this code to the karate demos at some point, if ok with you – Peter Thomas Sep 06 '18 at 19:10
  • 1
    https://jwt.io/ might have something. They certainly have hard-coded strings and a nice debugger. I'm just not sure about a token on a header or cookie. Do you have a particular style you like the demos to be in? I'm happy to contribute one as a PR. – Loren Sep 07 '18 at 12:32
  • thanks ! you can use the OAuth2 example as a reference: https://github.com/intuit/karate/blob/master/karate-demo/src/test/java/demo/oauth/oauth2.feature – Peter Thomas Sep 07 '18 at 13:06
1

I'm pretty sure that Buffer is advanced / non-standard or NodeJS so it probably is not supported by the JS engine that Karate uses (Graal).

Here's my recommendation. For this case, do the work using Java utilities.

For example, look at the Karate basic-auth example in the doc which uses Base64 encoding.

If it is really complex, simply create a Java static function, it will be much easier to test as a side-benefit. Hope this helps !

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • Thanks a lot, @Peter Thomas, I tried everything in JS and finally I used Java: public static String getWishedClaim(String token, String yourClaim){ String result = null; try { DecodedJWT jwt = JWT.decode(token); result = jwt.getClaim(yourClaim).asString(); } catch (JWTDecodeException exception){ //Invalid token } return result; } and in my feature I call this static method. I start to understand better your tutorials. – cygne Sep 27 '17 at 23:34
  • write a normal Java method so you can test it there before using in Karate. Take the help of someone who knows about the decoding you are trying to do. – Peter Thomas Sep 28 '17 at 08:34
  • We tried this in Java and it works, but in Karate not: `* def decoder = """ function(token) { var Base64 = Java.type("java.util.Base64"); var getB = Base64.getDecoder().decode(token.getBytes()); var decoded = new String(getB); return decoded; } """`, then we tried without `var decoded = new String(getB);` and added `* string dec = decoder token` but it doesn't work. I'm sorry to disturb you, @Peter Thomas, but if we could manage that 'new String' directly in a feature, it'll be really very helpful. Thanks in advance – cygne Sep 28 '17 at 09:38
  • sorry can't make sense of this. best option is raise a defect, but you must include a clear, simple working example that can replicate the issue. – Peter Thomas Sep 28 '17 at 09:44
-1

With respect to the post Karate: Problem with requests using bearer token | Karate is showing "org/apache/commons/codec/binary/Base64" in response instead of HTTP 401

My query was marked duplicate hence posting an answer/solution which we have found in our project.

We did some debugging in karate core about the error. It seemed a dependency was missing.

enter image description here

We added the dependency in the POM.xml

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.15</version>
</dependency>

Afterwards the problem was resolved and we started getting HTTP 401. I am not sure it can be added to the karate core.

Rajesh Dutta
  • 229
  • 1
  • 5