使用 Node.js 和 SPA 进行 SAML2.0 身份验证

Posted

技术标签:

【中文标题】使用 Node.js 和 SPA 进行 SAML2.0 身份验证【英文标题】:SAML2.0 Authentication with Node.js and SPA 【发布时间】:2017-11-19 11:02:00 【问题描述】:

大约 2 天来,我一直在摸索如何解决看似简单的任务,但它开始让我发疯。

我有一个应用程序,用户将使用 SAML 2.0 进行身份验证。 我为前端设置了一个 react-application,并且正在考虑使用 JWT 来保护前端和后端之间的 rest-api 通信。

当用户登录时,流程如下:

    用户访问 www.server.com/ 并通过 react-application 获得静态 html 用户点击“登录”并访问 www.server.com/login passport-saml 将用户重定向到 saml 身份提供者。用户登录。 用户使用 req.body 中的 SamlResponse 回调 www.server.com/callback,该 SamlResponse 由 passport-saml 解码并放入 req.user。 如果用户不存在,我会在数据库中创建用户。 我创建了一个 JWT。

接下来我该怎么做?问题是当从身份提供者回调时用户不在反应应用程序中,所以我丢失了应用程序中的所有状态,所以无论我回复什么都会发送到浏览器。

有什么办法可以强制浏览器给我身份提供者正在回调的 SamlResponse?然后我可以将它作为来自 react-application 的 http-request 发送到服务器。

【问题讨论】:

海你能分享一些样本我有同样的问题 【参考方案1】:

经过一番思考,我想出了以下解决方案,对我来说效果很好。

SAML 有一个名为RelayState 的东西,它是服务提供者必须响应的属性。所以现在这个过程是这样的:

    用户访问http://frontendserver.com 并使用 React 应用程序(未登录)获取服务器静态页面。 用户单击“登录”并被重定向到http://backendserver.com/login/?RelayState=http://frontendserver.com,该http://backendserver.com/login/?RelayState=http://frontendserver.com 通过passport-saml 进行身份验证并将用户重定向到SP。所以我在 RelayState 中传递了请求的来源。 用户使用包含 RelayState 的 SamlResponse 回调到 http://backendserver.com/callback。 我创建了一个令牌,并将用户重定向到RelayState/#token。 然后我可以在 React 应用程序中解析 url,并将令牌添加为任何进一步请求的标头。

这似乎是显而易见的方法,但我花了很长时间才弄清楚这是否可行。

【讨论】:

只要通过 https 进行通信就不会。 你能提供一个示例应用吗? 我下次访问网站时如何注销并检查令牌是否有效 @ankalal JWT 没有干净的退出方式。我在我的应用程序上所做的是,如果用户单击注销,我只需从 cookie 中删除他们的令牌。如果您需要将用户从服务器注销(比如说删除它们),您必须有一种机制来跟踪服务器上的令牌(例如 db)并使它们无效。 拜托,请您添加更多详细信息。我得到 SAMLResponse 并再次使用 302 状态代码重定向到 web-app,但是由于 302,浏览器阻止了来自 JS 的任何访问。所以这一步“用户使用包含 RelayState 的 SamlResponse 回调backendserver.com/callback”。应该以哪种方式完成?检测重定向?【参考方案2】:

我知道这个问题是针对 Node 后端的,但是我找到了一篇 php/Apache 网络服务器后端实现的文章here,我认为它可以帮助试图理解这种类型的流程的人一切正常。

【讨论】:

以上是关于使用 Node.js 和 SPA 进行 SAML2.0 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何创建服务于 Vue.js SPA 的 Node.js Express 应用程序?

如何使用Backbone和Node.js / Hapi防止CORB错误?

如何设置本地测试 SAML2.0 身份提供程序?

使用 Angular、node.js 和身份提供者的 SAML 身份验证

WSO2IS + node.js passport-saml 集成错误

什么是 Node.js 样式模块?