4

i am trying to implement a single sign on for my web application. I am using gravitee.io for the access managment and token generation. I followed the steps in gravitees quickstart tutorial and i am now at the point that i want to verify my id_token.

In order to do that i am using the node-jsonwebtoken library. i am using total.js for my backend (which should not be as important, but i still wanted to mention it).

What i have done so far. i have my client-id and my client-secret as well as my domain secret in the total.js config file

./configs/myconfig.conf (key/secret is changed)

url                 : https://sso.my-graviteeInstance.com/am
client-id           : myClientId
client-secret       : uBAscc-zd3yQWE1AsDfb7PQ7xyz
domain              : my_domain
domain-public-key   : EEEEEB3NzaC1yc2EAAAADAQABAAABAQCW4NF4R/sxG12WjioEcDIYwB2cX+IqFJXF3umV28UCHZRlMYoIFnvrXfIXObG7R9W7hk6a6wbtQWERTZxJ4LUQnfZrZQzhY/w1u2rZ3GEILtm1Vr1asDfAsdf325dfbuFf/RTyw666dFcCcpIE+yUYp2PFAqh/P20PsoekjvoeieyoUbNFGCgAoeovjyEyojvezxuTidqjaeJvU0gU4usiiDGIMhO3IPaiAud61CVtqYweTr2tX8KabeK9NNOXlTpLryBf3aTU1iXuU90mijwXZlmIzD28fWq+qupWbHcFZmmv3wADVddnxZHnFIN7DHGf5WVpb3eLvsGkIIQpGL/ZeASDFa

i added a model to handle the login workflow for total.js in order to get the jwt tokens from gravitee by REST-call. So far everything works as expected. a session is created and stores the response in it. the gravitee response is the expected json which looks like this

{
  access_token: 'some-long-token',
  token_type: 'bearer',
  expires_in: 7199,
  scope: 'openid',
  refresh_token: 'another-long-token',
  id_token: 'last-long-token'
}

I split up the tokens in seperate cookies because when i tried to save them as a single cookie, i got an error that told me the cookie exceeds the 4096 length limit.

So far everything works just fine. in the frontend ajax call the success callback will be executed, just setting the window.location.href='/'; to call the dashboard of my application. I set this route to be accessible only when authorized, so that when my dashboard is called, the onAuthorize function is called by totaljs.

F.onAuthorize = function (req, res, flags, callback) {
  let cookie = mergeCookies(req.cookie);
  
  // Check the cookie length
  if (!cookie || cookie.length < 20) {
    console.log(`cookie not defined or length to low`);
    return callback(false);
  }

  if (!cookie) {
    console.log(`cookie undefined`);
    return callback(false);
  }

  // Look into the session object whether the user is logged in
  let session = ONLINE[cookie.id];
  if (session) {
    console.log(`there is a session`);
    // User is online, so we increase his expiration of session
    session.ticks = F.datetime;

    jwt.verify(
      session.id_token, 
      Buffer.from(CONFIG('client-secret')).toString('base64'),
      function(err, decoded){
        if (err) {
          console.log(`jwt verify error: ${err}`);
          return callback(false);
        }
        console.log(`decoded token user id: ${decoded.sub}`);
        return callback(true, session);
      })
  }
  console.log(`false`);
  callback(false);
};

I also tried to just send the CONFIG('client-secret') without buffering. I also tried to send the CONFIG('domain-public-key'). But the error i get is always the same:

jwt verify error: JsonWebTokenError: invalid algorithm

When i copy and paste the id_token into the debugger at jwt.io with algorithm beeing set to RS256 i'll see the following decoded values:

// header
{
  "kid": "default",
  "alg": "RS256"
}

// payload
{
  "sub": "some-generated-id",
  "aud": "myClientId",
  "updated_at": 1570442007969,
  "auth_time": 1570784329896,
  "iss": "https://sso.my-graviteeInstance.com/am/my_domain/oidc",
  "preferred_username": "myUsername",
  "exp": 1570798729,
  "given_name": "Peter",
  "iat": 1570784329,
  "family_name": "Lustig",
  "email": "peter.lustig@domain.com"
}

i copied the public key from my domain in to the respective textfield and i also tried to use the client-secret. no matter what i do, the error i am getting here is

Warning: Looks like your JWT signature is not encoded correctly using base64url (https://www.rfc-editor.org/rfc/rfc4648#section-5). Note that padding ("=") must be omitted as per https://www.rfc-editor.org/rfc/rfc7515#section-2

I dont understand why there is an algorithm error when i try to verify the token in my backend and some encoding error at jwt.io debugger.

can somebody explain to me on how to fix the issue? Thanks in advance Pascal

edit: changed title

Community
  • 1
  • 1
JustAMicrobe
  • 427
  • 6
  • 15
  • 5
    I believe that you need to specify the algorithm `jwt.verify(token, MYSECRET, { algorithms: ['RS256'] });` where MYSECRET is the content of the .pem certificate which should contain `-----BEGIN RSA PRIVATE KEY-----` and `-----END RSA PRIVATE KEY-----` or PUBLIC instead of PRIVATE – Molda Oct 11 '19 at 14:43
  • @Molda that solved the issue! thanks a lot. i thought it would automatically detect the algorithm since it is given in the header. However, now my public key seems to be wrong. i am now getting a new error: jwt verify error: Error: PEM_read_bio_PUBKEY failed. but i guess i can solve this by googling a little bit and some more trial and error. Could you post your answer so i can accept it? thanks a lot – JustAMicrobe Oct 14 '19 at 07:05

0 Answers0