使用Okta OIDC中间件时出现“错误:状态不匹配,在会话中找不到状态”

时间:2019-09-10 16:33:53

标签: node.js express okta openid-connect okta-api

我们正在为我们的Web应用设置Okta oidc中间件。

有效的是,当我们没有登录时,我们被重定向到Okta,然后在提供有效的凭据后被重定向回我们的回调处理程序。在本地进行测试时,回调会收到身份验证代码,我们将被重定向到after回调路径。

但是,在我们部署的登台服务器上,回调函数会收到代码,但会返回401。

这里有一个类似的问题目前尚未解决:https://github.com/okta/okta-oidc-js/issues/207

可能与此无关,尽管错误消息相同,但所描述的情况并不完全相同。

有人对这个问题可能是什么或如何提高日志记录的详细程度有任何想法吗?

我不认为这是由于登录重定向URI的配置错误造成的。我们已经添加了必需的路径。

Express设置中的Okta配置如下:

const MemoryStore = require('memorystore')(session);
app.use(
  session({
    store: new MemoryStore({
      checkPeriod: 86400000,
    }),
    secret: process.env.OKTA_SESSION_SECRET,
    resave: true,
    saveUninitialized: false,
    cookie: {
      maxAge: 30 * 60 * 1000,
      httpOnly: false,
    },
  })
);

const orgUrl = process.env.OKTA_ORG_URL;
const oidc = new ExpressOIDC({
  appBaseUrl: process.env.OKTA_APP_BASE_URL,
  issuer: `${orgUrl}/oauth2/default`,
  client_id: process.env.OKTA_CLIENT_ID,
  client_secret: process.env.OKTA_CLIENT_SECRET,
  scope: 'openid profile',
  routes: {
    login: {
      path: `${APP_ROOT}/login`,
    },
    loginCallback: {
      path: `${APP_ROOT}/authorization-callback`,
      afterCallback: APP_ROOT,
    },
  },
});
app.use(oidc.router);

这是服务器日志中弹出的错误:

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 (/usr/src/app/node_modules/openid-client/lib/passport_strategy.js:169:20)
    at <anonymous>
    at runMicrotasksCallback (internal/process/next_tick.js:121:5)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickDomainCallback (internal/process/next_tick.js:218:9)

2 个答案:

答案 0 :(得分:1)

为了保护免受CSRF攻击,OAUTH 2.0希望客户端生成一个随机的“状态”,将其存储在会话中,并将其作为验证端点的参数发送给您的IdP。

IdP返回响应时,它回显客户端发送的相同状态。 如果它们不同,则身份验证被拒绝。

您的问题似乎表明此状态参数未正确存储在客户端会话中。

也许您有节点后端的多个实例,但是没有粘性会话?在这种情况下,将状态存储在会话中的实例可能与从IdP获取响应回调的实例不同。

答案 1 :(得分:0)

由于我们部署的服务器通过至少一层服务器代理,因此状态信息在转换时会丢失。我们使用以下方法解决:https://github.com/expressjs/cookie-session