代理后面的护照不持久会话

问题描述 投票:0回答:1

情况

我有一个用 React 编写的前端,以及一个处理 SAML 身份验证过程 (Azure AD) 的 Express 后端服务器。该后端可通过为 React 应用程序提供服务的 nginx 服务器进行访问:它代理将

/api
为前缀的所有请求传递到后端。这样客户端不知道后端,只有 nginx 知道。

Schema of the architecture

问题是 Passport 似乎不适用于此设置。事情是这样发生的:

  1. 客户端点击认证按钮,React请求路由
    /api/login
  2. NGINX 代理将此请求传递到我的后端,由护照接管。
  3. 客户端通过IDP表单成功登录,Passport正确处理回调函数(我解析从IDP收到的配置文件,我在后端接收用户)。
  4. 后端将客户端重定向到
    /home
    路由,但请求会话未保存或似乎从未转发到客户端,从而导致客户端经过身份验证。

代码

这里是

app.js
中的Passport初始化:

app.set('trust proxy', 1)
app.use(
  session({
    cookie: {
      path: '/',
      secure: true,
      httpOnly: false,
      sameSite: 'none',
      domain: `https://${process.env.FRONTEND_DOMAIN}`
    },
    resave: false,
    saveUninitialized: true,
    secret: 'TOI_MEME_TU_LE_C'
  })
)
app.use(passport.initialize())
app.use(passport.session())

这是我在 Express 中的回调路线:

router.post('/saml/acs', bodyParser.urlencoded({ extended: false }), (req, res, next) => {
  passport.authenticate('saml', (err, user) => {
    if (err) {
      let error = 'generic'
      if (err.message.includes('RequestDenied')) {
        error = 'request_denied'
      } else if (err.message.includes('unspecified')) {
        error = 'unspecified'
      }

      return res.redirect(`https://${process.env.FRONTEND_DOMAIN}/login?error=${error}`)
    }

    console.log(`${user.firstname} ${user.lastname} (${user.employeeId ?? '-> no employeeId <-'}) is connected.`)

    req.login(user, error => {
      if (error) {
        console.log('Erreur lors du login.', error)
        return next(error)
      }

      console.log('Login successful, is authenticated?: ' + req.isAuthenticated())

      return res.redirect(`https://${process.env.FRONTEND_DOMAIN}`)
    })
  })(req, res, next)
})

请注意,两个日志均正确显示!第二个表明

req.isAuthenticated()
有效并返回 true。

这里是客户端虽然已成功连接,但仍未通过后端身份验证的地方(这是经典的

/me
路线):

router.get('/me', (req, res) => {
  // it never goes past here, as neither the metho nor the user object exist in the request
  if (!req.isAuthenticated()) {
    return res.status(401).send({ error: "Not connected." })
  }

  if (!req.user) {
    return res.status(500).send({ error: "No user on the request." })
  }

  res.status(200).json(req.user)
})

我尝试删除 Passport 回调中的自定义错误处理,但没有任何效果。 我尝试更改cookie设置,没有效果。

为什么 Passport 无法正确检测身份验证?

javascript express nginx passport.js saml
1个回答
0
投票

您的

nginx
配置也与此处相关。在不知道的情况下,我只能提供最好的猜测。对于在会话配置中设置
secure: true
的配置,您还必须配置
nginx
来转发协议,例如:

proxy_set_header X-Forwarded-Proto $scheme;

您可以提出一些其他问题来帮助您找出问题:

  • 本地可以用吗?如果是这样,问题可能出在 nginx 上。
  • 如果删除
    secure: true
    是否有效?如果是这样,
    nginx
    可能并不表示请求是通过
    https
    传入的。请参阅上面的
    proxy_set_header
    指令。
  • nginx
    是否通过
    https
    http
    为网站提供服务?
    https
    secure: true
    属性的要求。

有关类似问题,请参阅Express-session Secure Cookies 不起作用

请参阅 https://gist.github.com/nikmartin/5902176 获取可能会给您一些其他尝试想法的食谱。

© www.soinside.com 2019 - 2024. All rights reserved.