hapijs / nes

WebSocket adapter plugin for hapi routes
Other
502 stars 87 forks source link

Non standard browser cookie in Nes authentication #317

Closed indrajit-kanjilal closed 3 years ago

indrajit-kanjilal commented 3 years ago

Support plan

Context

How can we help?

I have a OIDC server integration which adds a non-standard cookie in my browser session. Due to this cookie, any request I make from my angular application to HAPI server, shall generate error, I get rid of these errors by adding "failAction: 'log'

 routes: { 
          log: { collect: true },
          files: { // for the "inert" plugin, serves static ng libs
              relativeTo: Path.join(__dirname, 'public')
          },
          state: {
            parse: true,
            failAction: 'log'
          }
      }

in my HAPI server configuration.

My angular application uses the "hapi-auth-jwt2": "^10.2.0" plugin for route authentication.

await server.register([
      {   plugin: OIDC,  //For OIDC authentication
          options: conf.client_options
      },
      /*{ plugin: Vision } We shall use angular, not needed anymore*/
      {   plugin: Inert  }, // This will provide static site for loading the angular files
      {   plugin: HapiJwt  }  // For Angular UI authentication
  ]);

  server.auth.strategy('oidc', 'oidc', {
      password: uuidv4()
  });

  server.auth.strategy('jwt', 'jwt',
  {   key: 'mysupersecretkey', 
      validate: validate  // validate function defined above
  });

Then I create the Nes server

const nesOptions = {
    auth: {
        type: 'direct',
        route: {strategy: 'jwt'},
        password: 'mysupersecretkey'
    }
  }

  await server.register({plugin: Nes, options: nesOptions});

In my angular app , I create the client

this.client = new Nes.Client(wsServerUrl);
.................
async onClientInitiate(){
    const cliConnectOption = {
        auth: {
          headers: {
            authorization: `Bearer ${sessionStorage.getItem('jwt')}`
          }
        }
    };

    try {
      await this.client.connect(cliConnectOption);
      console.log(`Nes connection complete`);
    }
    catch (err){
      console.log(`Nes connect error: ${JSON.stringify(err)}`);
    }

This works like a charm in my incognito window, however with a non-incognito window , I keep getting (In chrome dev console):

Nes connect error: {"type":"server","isNes":true,"statusCode":401,"data":{"error":"Unauthorized","message":"Invalid nes authentication cookie"}}

After looking closely , I see that "socket.js" in Nes plugin is executing the following code:

    try {
        var { states } = await this.server.states.parse(cookies);
    }
    catch (err) {
        throw Boom.unauthorized('Invalid nes authentication cookie');
    }

With my invalid cookies, I guess that this manual cookie parse step is failing and generating exception.

My questions are: 1) Is there a way I can make this work ? 2) Is it necessary to parse all cookies when my authentication type is "direct"? can there be a option not to do the manual parsing or provide a "failAction" ?

Thank you

indrajit-kanjilal commented 3 years ago

Found the solution, kindly close and ignore. The trick is to set "strictHeader: false" and "ignoreErrors: true" in server options

var server = new Hapi.Server({
      address: 'inmbzp5164.in.dst.ibm.com', 
      port: 7832, 
      tls: tls, 
      routes: { 
          log: { collect: true },
          files: { // for the "inert" plugin, serves static ng libs
              relativeTo: Path.join(__dirname, 'public')
          },
          state: {
            parse: true,
            failAction: 'log'
          }
      },
      state: {
        strictHeader: false,
        ignoreErrors: true,
      }
  });