Okta OIDC跳转模式下分步认证异常问题求助
问题:Okta跳转模式下分步认证触发全量认证而非仅Okta Verify 2FA
我使用Okta的redirect model(跳转模式)实现用户登录,登录流程中用户需输入登录凭证并通过Okta Verify完成2FA认证。用户成功登录并建立认证会话后,在访问受限资源前调用/auth/2fa端点,期望仅触发Okta Verify的分步认证(Step-Up authentication),但实际却被要求输入密码+Okta Verify,等同于重新认证而非分步认证。我不确定是否是认证策略配置问题,若为配置问题,请告知正确的策略设置方式,当前我已在此处受阻无法推进。
相关代码
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var session = require('express-session'); var passport = require('passport'); var qs = require('querystring'); var { Strategy } = require('passport-openidconnect'); const axios = require('axios'); const crypto = require('crypto'); // source and import environment variables require('dotenv').config({ path: '.okta.env' }) //require('dotenv').config({ path: '.entra.env' }) const { ORG_URL, CLIENT_ID, CLIENT_SECRET, CALLBACK_URL } = process.env; var indexRouter = require('./routes/index'); const { profile } = require('console'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use(session({ secret: 'CanYouLookTheOtherWay', resave: false, saveUninitialized: true, // cookie: { secure: true, sameSite: false } })); // app.set("trust proxy", 1); app.use(passport.initialize()); app.use(passport.session()); // https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest let logout_url, id_token; let _base = ORG_URL.slice(-1) == '/' ? ORG_URL.slice(0, -1) : ORG_URL; console.log ('Base URL - ' + _base); axios .get(`${_base}/.well-known/openid-configuration`) .then(res => { if (res.status == 200) { let { issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, end_session_endpoint } = res.data; logout_url = end_session_endpoint; console.log ('Authorization Endpoint - ' +authorization_endpoint); const riskyActionInfo = { action: 'Login Button', referURL: '/', targetURL: '/profile' }; //const state = JSON.stringify(riskyActionInfo); const state = JSON.stringify(riskyActionInfo); // Set up passport passport.use('oidc', new Strategy({ issuer, authorizationURL: authorization_endpoint, tokenURL: token_endpoint, userInfoURL: userinfo_endpoint, clientID: CLIENT_ID, clientSecret: CLIENT_SECRET, callbackURL: CALLBACK_URL, scope: ['openid', 'profile', 'email'], state: true, nonce: true, maxAge: 5, }, (issuer, profile, context, idToken, accessToken, refreshToken, params, done) => { console.log(`OIDC response: ${JSON.stringify({ issuer, profile, context, idToken, accessToken, refreshToken, params }, null, 2)}\n*****`); id_token = idToken; return done(null, profile); })); } else { console.log(`Unable to reach the well-known endpoint. Are you sure that the ORG_URL you provided (${ORG_URL}) is correct?`); } }) .catch(error => { console.error(error); }); passport.serializeUser((user, next) => { next(null, user); }); passport.deserializeUser((obj, next) => { next(null, obj); }); function ensureLoggedIn(req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect('/login') } app.use('/', indexRouter); app.use('/login', passport.authenticate('oidc')); app.use('/authorization-code/callback', // https://github.com/jaredhanson/passport/issues/458 passport.authenticate('oidc', { failureMessage: true, failWithError: true }), (req, res) => { console.log ("IN Callback Handler"); const returnedState = req.query.state; let st = req.authInfo.state; console.log("State :" + st); if (st === undefined) { console.log("state is null or undefined"); res.redirect('/profile'); } else { console.log(JSON.parse(st).targetURL); var url = JSON.parse(st).targetURL; res.redirect(url); } } ); app.use('/profile', ensureLoggedIn, (req, res) => { res.render('profile', { authenticated: req.isAuthenticated(), user: req.user, title: 'Profile' }); }); app.use('/secure_page', ensureLoggedIn, (req, res) => { res.render('secure_page', { authenticated: req.isAuthenticated(), user: req.user, title: 'Secure Page' }); }); app.use('/auth/2fa', ensureLoggedIn, (req,res) =>{ console.log ("******In MFA Page******"); const state = JSON.stringify({ action: 'secure_page', targetURL: '/secure_page' }); const nonce = crypto.randomBytes(16).toString('hex'); passport.authenticate('oidc', { scope: ['openid', 'profile', 'email','offline_access'], state: state, nonce: nonce, acrValues: 'phrh', maxAge:'0', })(req, res); }); app.get('/logout', (req, res) => { req.logout(); req.session.destroy(); res.redirect('/'); }); // catch 404 and forward to error handler app.use(function (req, res, next) { next(createError(404)); }); // error handler app.use(function (err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message + (err.code && ' (' + err.code + ')' || '') + (req.session.messages && ": " + req.session.messages.join("\n. ") || ''); res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
内容的提问来源于stack exchange,提问作者Pawan
相关产品推荐
相关产品推荐

