Passport-openidconnect login fails

I have been following the guides (Sign users in to your web app using the redirect model | Okta Developer and Node authentication with Passport.js and OpenID Connect) for using nodejs and passport to handle user logins, and they just aren’t working. I always get a 404, which seems to be from the /error endpoint from the failureRedirect: /error config in the /pl/oidcallback endpoint.

The code is almost completely copy and pasted from those guides (the only major difference is my callback url), but I’m assuming something has changed in the 5 years since they were created that I’m missing.

From what I can gather, it seems like passport just isn’t doing anything once it receives the code on the callback, I can see both the code and the state in the get log, but nothing happens and it redirects to the /error endpoint.

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

app.use(passport.initialize());
app.use(passport.session());

passport.use('oidc', new Strategy({
  issuer: 'https://{okta dev id}.okta.com/',
  authorizationURL: 'https://{okta dev id}.okta.com/oauth2/default/v1/authorize',
  tokenURL: 'https://{okta dev id}.okta.com/oauth2/default/v1/token',
  userInfoURL: 'https://{okta dev id}.okta.com/oauth2/default/v1/userinfo',
  clientID: {id},
  clientSecret: {secret},
  callbackURL: 'http://localhost:3000/pl/oidcallback',
  scope: 'openid profile'
}, (issuer, profile, done) => {
  return done(null, profile);
}));

passport.serializeUser((user, next) => {
  next(null, user);
});

passport.deserializeUser((obj, next) => {
  next(null, obj);
});

...

app.use('/login', passport.authenticate('oidc'));

app.use('/pl/oidcallback',
  passport.authenticate('oidc', { failureRedirect: '/error' }),
  (req, res) => {
    res.redirect('/profile');
  }
);

function ensureLoggedIn(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }

  res.redirect('/login')
}

app.use('/profile', ensureLoggedIn, (req, res) => {
  res.render('profile', { title: 'Express', user: req.user });
});

app.get('/logout', (req, res) => {
  req.logout();
  req.session.destroy();
  res.redirect('/');
});

After adding failureMessage: true, failWithError: true and removing failureRedirect from the passport config, I get the following error as a response:

Forbidden
403

AuthenticationError: Forbidden
    at allFailed (okta-node-passport-oidc-example/node_modules/passport/lib/middleware/authenticate.js:175:21)
    at attempt (okta-node-passport-oidc-example/node_modules/passport/lib/middleware/authenticate.js:183:28)
    at strategy.fail (okta-node-passport-oidc-example/node_modules/passport/lib/middleware/authenticate.js:305:9)
    at okta-node-passport-oidc-example/node_modules/passport-openidconnect/lib/strategy.js:171:56
    at okta-node-passport-oidc-example/node_modules/oauth/lib/oauth2.js:209:7
    at passBackControl (okta-node-passport-oidc-example/node_modules/oauth/lib/oauth2.js:134:9)
    at IncomingMessage.<anonymous> (okta-node-passport-oidc-example/node_modules/oauth/lib/oauth2.js:157:7)
    at IncomingMessage.emit (node:events:526:35)
    at endReadableNT (node:internal/streams/readable:1408:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

It looks like you are encountering a 403 Forbidden error with an AuthenticationError. This error typically occurs when the user authentication fails or when there’s an issue with the authorization process.

To troubleshoot and resolve the issue, here are a few suggestions:

  1. Check Okta Developer Console Logs:
  • Visit the Okta Developer Console and navigate to the “System Log.”
  • Look for any recent log entries related to the authentication attempts. This might provide additional details on why the authentication failed.
  1. Verify Issuer URL:
  • Ensure that the issuer URL in your Okta Passport strategy matches the correct Okta authorization server URL.
  • Double-check that your Okta authorization server is correctly configured with the expected client ID and client secret.
  1. Check for Clock Skew:
  • Ensure that the system clocks on your server and Okta are synchronized. A clock skew could lead to authentication failures.
  1. Update Dependencies:
  • Ensure that you are using the latest versions of the Okta Node.js SDK, Passport, and related dependencies. Outdated dependencies may have compatibility issues.
  1. Review Okta Policies:
  • Check the Okta policies associated with your application, user, or group. Ensure that there are no policies preventing the user from authenticating.
  1. Error Handling:
  • Implement better error handling in your Passport authentication callback. Print out or log any error details to get more insights into what might be causing the Forbidden error.

Here’s an example of how you can enhance error handling in your callback:

app.use('/pl/oidcallback',
  passport.authenticate('oidc', { failureMessage: true, failWithError: true }),
  (err, req, res, next) => {
    if (err) {
      console.error(err); // Log the error for debugging
      return res.status(403).json({ message: 'Forbidden' });
    }
    res.redirect('/profile');
  }
);

Implementing these steps should help you identify and address the root cause of the Forbidden error. If the issue persists, please provide additional details or error messages for further assistance.

1 Like

Hi there @edek

You might try comparing your code to this project. It’s the one the DevRel team maintains for quick scaffolding using the Okta CLI.

Let us know how it works out for you!

This was my issue, thanks! I didn’t realize the issuer url included the /oauth2/default/v1 part

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.