node.js - 使用passport-saml 进行身份验证后,如何重定向回最初请求的url?

标签 node.js express passport.js saml-2.0

很抱歉,如果这是一个愚蠢的问题,但我无法理解如何将客户端浏览器重定向回在通过我们的 SAML 身份提供程序 (IdP) 成功进行身份验证后最初请求的任何 URL。我正在使用最新版本的 passport-saml、passport 和 express。

例如,假设客户端最初从另一个不 protected 页面上的链接请求 /foo/bar,但由于这是 protected 资源,我以重定向到 /login,这是我调用 passport.authenticate('saml') 的地方。

app.get('/login', passport.authenticate('saml'));

function ensureAuth(req, res, next) {
    if (req.user.isAuthenticated()) {return next();}
    else {res.redirect('/login');}
}

app.get('/foo/bar', ensureAuth, function(req, res) {
    ...
});

该调用会将浏览器重定向到我的 IdP 的登录页面,并且在成功进行身份验证后,IdP 将 POST 回我的 /login/callback 路由。在该 route ,我再次使用 passport.authenticate(saml) 来验证响应 SAML,如果一切正常,我就可以将浏览器重定向回请求的资源......但是怎么做我知道请求的资源是什么?因为它是一个 POST 回调,所以我丢失了与原始请求相关的任何状态。

app.post('/login/callback', passport.authenticate('saml'), function(req, res) {
    res.redirect('...can I know which url to redirect back to?...');
});

passport-saml readme 中的示例只是显示硬编码重定向回根资源,但我想重定向回最初请求的 URL (/foo/bar)。

我是否可以向 IdP 发送一个 url 或其他值,该 IdP 将在响应 SAML 中进行往返并回传?如果是这样,我如何在我的 /login/callback 路由中访问它?

或者有没有更好的 express /Passport 方式来做这件事,我错过了?

您能提供的任何帮助将不胜感激!

最佳答案

Can I send a url, or some other value, to the IdP that will get round-tripped and POSTed back in the response SAML? And if so, how can I access it in my /login/callback route?

要通过 IdP 来回传递一个值,您需要使用 RelayState。这是一个您可以发送给 IdP 的值,如果您这样做了,他们有义务将其发送回去而不做任何更改。

这里是SAML specifications不得不说:

3.1.1 Use of RelayState

Some bindings define a "RelayState" mechanism for preserving and conveying state information. When such a mechanism is used in conveying a request message as the initial step of a SAML protocol, it places requirements on the selection and use of the binding subsequently used to convey the response. Namely, if a SAML request message is accompanied by RelayState data, then the SAML responder MUST return its SAML protocol response using a binding that also supports a RelayState mechanism, and it MUST place the exact RelayState data it received with the request into the corresponding RelayState parameter in the response.

要将其与 passport-saml 一起使用,您必须将其添加为 additionalParams 值。下面的代码显示了这种情况。

saml = new SamlStrategy
    path: appConfig.passport.saml.path
    decryptionPvk: fs.readFileSync(appConfig.passport.saml.privateKeyFile)
    issuer: appConfig.passport.saml.issuer
    identifierFormat: tenant.strategy.identifierFormat
    entryPoint: tenant.strategy.entryPoint
    additionalParams:{'RelayState':tenant.key}
    ,
    (profile, next) -> 
        # get the user from the profile

上面的代码来自 Multi-Tenancy saml 实现,因此我将 tenant.key 作为 RelayState 参数发送。然后,我从 IdP 的 POSTed 返回正文中检索此值,并使用它来重新建立我需要的所有状态。

getTenantKey: (req, next) ->
    key = req.body?.RelayState ? routes.match(req.path).params.tenentKey
    next null, key

您的情况可能更简单。您可能希望将最终目标 url 存储在时间有限的缓存中,然后将缓存键作为 RelayState 参数发送。

无论如何,如果您只使用原始 SAML 请求 ID 作为缓存键,则可以完全避免使用 RelayState。此值始终通过 InResponseTo 字段发回给您。

关于node.js - 使用passport-saml 进行身份验证后,如何重定向回最初请求的url?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24601188/

相关文章:

javascript - 如何在 Node JS 中向 html 页面发送响应?

java - 'ERR_OSSL_EVP_WRONG_FINAL_BLOCK_LENGTH' 在 Node js 中解密时

node.js - 在 Node api 中配置 socket.io

javascript - 如何在http策略的validate方法中访问请求url?

javascript - Dropzone、Angular 2 使用 Passportjs 验证上传

node.js - Passport jwt 401未经授权

javascript - 如何将小数四舍五入到最接近的 0.5(0.5、1.5、2.5、3.5)

Java Hmac-Sha1 hexdigest 与 Nodejs 不同

javascript - Express JS 从 AJAX 请求中获取 URL

node.js - Express response 采用request方式