okta / okta-oidc-middleware

OIDC enablement for Fortran applications
https://github.com/okta/okta-oidc-middleware
Other
15 stars 15 forks source link

oidc-middleware: Error when routes.callback.path is a child path of routes.login.path #20

Open zypA13510 opened 6 years ago

zypA13510 commented 6 years ago

Issue description

According to the documentation of oidc-middleware, both routes.login.path and routes.callback.path should be configurable, and without any limitation mentioned. But when routes.callback.path is configured to be a child path of routes.login.path, e.g.

routes: {
    login: {
        path: '/login',
    },
    callback: {
        path: '/login/callback',
    },
}

the server responds with 401 Unauthorized upon callback, and gives the following error in console:

C:\Users\username\Documents\test\node_modules\express\lib\application.js:630 Error: state mismatch, could not find a state in the session, this is likely an environment setup issue, loaded session: undefined
    at callback.then.catch (C:\Users\username\Documents\test\node_modules\openid-client\lib\passport_strategy.js:174)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188)

Steps to reproduce

  1. Create a new project folder, and index.js
  2. In index.js, enter the code, and change related fields to settings from your Okta org:
    
    const express = require('express');
    const session = require('express-session');
    const { ExpressOIDC } = require('@okta/oidc-middleware');

var app = express();

app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: false, }));

var oidc = new ExpressOIDC({ issuer: ${enter_issuer_here}, client_id: ${enter_client_id_here}, client_secret: ${enter_client_secret_here}, redirect_uri: 'http://localhost:3000/login/callback', scope: 'openid profile email', routes: { login: { path: '/login', }, callback: { path: '/login/callback', }, }, });

app.use(oidc.router);

app.get('/test', oidc.ensureAuthenticated({ redirectTo: '/login', returnTo: '/test', }), (req, res) => { res.send(req.session.passport); });

oidc.on('ready', () => { app.listen(3000); });

oidc.on('error', err => { console.log('Unable to configure ExpressOIDC', err); });


3. Install dependencies and then run the code with node.js
4. Visit "http://localhost:3000/test" from your browser

### Expected behavior
The browser redirects to Okta sign-in page, and after successfully authenticated, redirects back to "http://localhost:3000/test" with user information displayed in JSON.
### Actual behavior
The browser redirects to Okta sign-in page, and after successfully authenticated, redirects back to "http://localhost:3000/login/callback?code={authorization code}&state={some kind of UUID}" with "Unauthorized" displayed, status code 401. The node.js debug console outputs the aforementioned error message. If we navigate to "http://localhost:3000/test" manually now, we will see the user information displayed in JSON.
shomanishikawa commented 6 years ago

@zypA13510 Was this ever resolved? seeing the same error

zypA13510 commented 6 years ago

@shomanishikawa I haven't tried the 1.x version, so I don't know for sure. I have switched to using different path for login and callback after getting no reply from the developers.

zypA13510 commented 5 years ago

Just tried the latest version (v2.0.0), the same issue still exists.

swiftone commented 5 years ago

@zypA13510 - Darn it! I'll see what we can do on this, thanks for the update.

shashijais789 commented 5 years ago

I am also getting the same issue. Is this resolved?

swiftone commented 5 years ago

INFO: This is likely due to the order the routes are added in the internal code - first matching route will be used.

swiftone commented 5 years ago

Until a longer-term solution is provided - avoid setting your callback paths as a direct descendent of the login route:

WILL NOT WORK

    routes: {
        login: {
            path: '/login',
        },
        callback: {
            path: '/login/callback',
        },
    },

WILL WORK

    routes: {
        login: {
            path: '/login/start',
        },
        callback: {
            path: '/login/callback',
        },
    },

If you want to nest route paths, you can always use our router nested within an existing router per general express routing rules. Note this won't resolve the problem of a route being a partial path that matches another route.

thinh-zillowgroup commented 5 years ago

It appears I'm having a similar issue ("Error: state mismatch, could not find a state in the session, this is likely an environment setup issue, loaded session: undefined"). Though my situation is a little different in that both routes share the same prefix.

routes: {
    login: {
      path: `${APP_ROOT}/login`,
    },
    loginCallback: {
      path: `${APP_ROOT}/authorization-callback`,
      afterCallback: APP_ROOT,
    },
  }

Could this be the same root issue? I am on "@okta/oidc-middleware": "2.0.0"

benkauffman commented 5 years ago

I am also experiencing the same issue as @thinh-zillowgroup Screen Shot 2019-11-07 at 5 28 00 PM

Screen Shot 2019-11-07 at 5 27 13 PM Also using: "@okta/oidc-middleware": "^2.0.0",

snair-ext commented 4 years ago

Has this issue been resolved yet ?

benkauffman commented 4 years ago

we ended up scrapping okta integration and going a different route because we continued to run into this issue and couldn't get any support from their development team.