2

我有一个 Azure Active Directory 租户,我希望通过在 Azure 应用服务实例上运行的 Node.js 应用程序对其进行身份验证。我正在使用 passportjs 和 passport-azure-ad 来执行此操作。

本地一切正常。我可以通过 Azure AD 租户进行身份验证,它会正确返回到我的页面。但是在 Azure 上失败并出现以下错误:

authentication failed due to: In collectInfoFromReq: invalid state received in the request

我的配置与我使用相同的租户进行本地测试以及在 Azure 中的配置完全相同(除了 redirectUrl),但它仍然失败。我已经设置了正确的回复 URL,并且身份验证返回到我的应用程序。

这是我的配置:

{
  identityMetadata: `https://login.microsoftonline.com/${tenantId}/.well-known/openid-configuration`,
  clientID: `${clientId}`,
  responseType: 'id_token',
  responseMode: 'form_post',
  redirectUrl: 'https://localhost:3000/auth/oidc/return',
  allowHttpForRedirectUrl: false,
  scope: [ 'openid' ],
  isB2C: false,
  passReqToCallback: true,
  loggingLevel: 'info'
}

我正在使用 OIDCStrategy。

我的身份验证中间件:

passport.authenticate('azuread-openidconnect', {
  response: res,
  failureRedirect: '/auth/error',
  customState: '/'
});

我比较了authorize请求上的编码状态与返回的响应,它们在本地和 Azure 上的不同之处相同,但 Azure 是唯一抱怨的。状态如何不同的示例:

Azure:
Request state:  CUSTOMEwAuZcY7VypgbKQlwlUHwyO18lnzaYGt%20
Response state: CUSTOMEwAuZcY7VypgbKQlwlUHwyO18lnzaYGt

localhost:
Request state:  CUSTOMTAYOz2pBQt332oKkJDGqRKs_wAo90Pny%2F
Response state: CUSTOMTAYOz2pBQt332oKkJDGqRKs_wAo90Pny/

我也尝试过完全删除 customState 但它仍然失败。

有人知道这里发生了什么吗?我是否配置不正确?

编辑:看来这可能不是护照天蓝色广告的问题。我还不确定,但一些调试显示我的应用程序的登录请求中没有 set-cookie 标头。会话已创建,但未设置 cookie,因此返回的响应无法查找包括状态在内的会话信息并进行比较。结果是它报告无效状态,因为它无法从会话中检索数据。

4

2 回答 2

3

原来问题是会话从未正确创建,因此没有process-azure-ad可比较的状态。这样做的原因是我已经配置express-session为使用安全会话 cookie,假设因为我通过https://...azurewebsites.net地址连接,所以连接是安全的。但从技术上讲,情况并非如此。

Azure 在 Web 应用程序前面运行一个负载均衡器,有效地代理从外部到我的应用程序的连接。此代理是安全连接终止的地方,然后流量以未加密的方式路由到我的应用程序。

Browser -(HTTPS)> Load balancer -(HTTP)> Application

结果是该节点没有将连接报告为安全,除非设置了配置选项trust proxy

app.set('trust proxy', true);

设置此选项时,express 将检查X-Forwarded-Proto用于连接代理服务器(在本例中为负载平衡器)的协议的标头。此标头包含 http 或 https,具体取决于连接协议。

对于 Azure,尽管这还不够。Azure 负载均衡器也不设置X-Forwarded-Proto标头。相反,它使用x-arr-ssl. 这不是一个大问题,因为 iisnode(我用来在 Azure 中的 IIS 上运行节点的运行时)有一个名为的选项enableXFF,它将X-Forwarded-Proto根据连接的外部协议更新标头。设置这两个选项可以express-session设置安全 cookie 来保存会话并允许passport-azure-ad存储和比较身份验证状态信息。

PS:非常感谢 Scott Smiths 博客 + 提供答案的评论: http: //scottksmith.com/blog/2014/08/22/using-secure-cookies-in-node-on-azure/

于 2018-01-29T06:44:32.353 回答
0

这是 module 的一个已知编码问题passport-azure-ad。看:

您可以将模块版本升级到v3.0.7或更新的版本来修复它。

于 2018-01-26T09:35:13.013 回答