Node.js ExpressJS/Passport SAML单次注销直接重新登录
目前,我正在NodeJS应用程序中开发passport saml实现。 这样做的原因是让我们的客户能够连接到他们的AD FS系统并利用SingleSignOn(SSO) 因为我们还想提供注销功能,所以我正在研究这个逻辑。然而,我似乎无法让这个简单的功能正常工作。我已经在谷歌上搜索了很多,尝试了很多变体和配置,但不幸的是,它不起作用 我想为我们的客户提供一种同时由SP和IdP驱动的单点注销(SLO)的可能性。这是我的出发点。在调试和开发过程中,我已经后退了一步,试图终止本地会话,但即使这样似乎也不可能 这是我为SAML配置的路由的相关代码:Node.js ExpressJS/Passport SAML单次注销直接重新登录,node.js,express,passport.js,adfs,passport-saml,Node.js,Express,Passport.js,Adfs,Passport Saml,目前,我正在NodeJS应用程序中开发passport saml实现。 这样做的原因是让我们的客户能够连接到他们的AD FS系统并利用SingleSignOn(SSO) 因为我们还想提供注销功能,所以我正在研究这个逻辑。然而,我似乎无法让这个简单的功能正常工作。我已经在谷歌上搜索了很多,尝试了很多变体和配置,但不幸的是,它不起作用 我想为我们的客户提供一种同时由SP和IdP驱动的单点注销(SLO)的可能性。这是我的出发点。在调试和开发过程中,我已经后退了一步,试图终止本地会话,但即使这样似乎也不
const isAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
// User logged in, pass on to next middleware
console.info('User authenticated');
return next();
}
// User not logged in, redirect to login page
console.info('User not authenticated');
return res.redirect('/login');
};
// GET-routes
app.get('/',
isAuthenticated,
(req, res) => {
res.send('Authenticated');
});
app.get('/login',
passport.authenticate('saml', {
successRedirect: '/',
failureRedirect: '/login/fail',
}));
app.get('/logout',
(req, res) => {
passport._strategy('saml').logout(req, (err, url) => {
return res.redirect(url);
});
});
// POST-routes
app.post('/adfs/callback',
(req, res, next) => {
passport.authenticate('saml', (err, user) => {
// If error occurred redirect to failure URL
if (err) return res.redirect('/login/fail');
// If no user could be found, redirect to failure URL
if (!user) return res.redirect('/login/fail');
// User found, handle registration of user on request
req.logIn(user, (loginErr) => {
if (loginErr) return res.status(400).send(err);
// Request session set, put in store
store.set(req.sessionID, req.session, (storeErr) => {
if (storeErr) return res.status(400).send(storeErr);
return res.redirect('/');
});
});
})(req, res, next);
});
app.post('/logout/callback', (req, res) => {
// Destroy session and cookie
store.destroy(req.sessionID, async (err) => {
req.logout();
return res.redirect('/');
});
});
可以看出,我控制了会话存储处理(设置和销毁会话,但如果这是不明智的,请给出建议)。
实现的会话存储是MemoryStore()
当用户登录时,一切正常。
然后一个请求被发送到route/logout,一些东西发生了,我可以看到会话发生了变化,会话ID以及passport saml的相关参数(nameID,sessionIndex)发生了变化,然后用户被重新路由到“/”
但是,用户将被视为未经身份验证,并被重新路由到“/login”。有人会争辩说,它到此为止,因为必须重新输入凭证。
情况并非如此,因为用户将直接再次登录,而无需重新输入凭据,我不知道如何防止这种情况
我真希望任何人都知道发生了什么:)
如果需要更多的信息,我很乐意听到。经过大量的研究和调查,我确实找到了解决这个问题的方法。 诀窍在于passport saml包的定义,特别是authncontext参数 因此,之前我将SamlStrategy选项定义为:
{
// URL that should be configured inside the AD FS as return URL for authentication requests
callbackUrl: `<URL>`,
// URL on which the AD FS should be reached
entryPoint: <URL>,
// Identifier for the CIR-COO application in the AD FS
issuer: <identifier>,
identifierFormat: null,
// CIR-COO private certificate
privateCert: <private_cert_path>,
// Identity Provider's public key
cert: <cert_path>,
authnContext: ["urn:federation:authentication:windows"],
// AD FS signature hash algorithm with which the response is encrypted
signatureAlgorithm: <algorithm>,
// Single Log Out URL AD FS
logoutUrl: <URL>,
// Single Log Out callback URL
logoutCallbackUrl: `<URL>`,
}
{
//应在AD FS中配置为身份验证请求返回URL的URL
callbackUrl:``,
//应在其上访问AD FS的URL
入口点:,
//AD FS中CIR-COO应用程序的标识符
发行人:,
地址:null,
//CIR-COO专用证书
私人证书:,
//身份提供者的公钥
证书:,
authnContext:[“urn:federation:authentication:windows”],
//用于加密响应的AD FS签名哈希算法
签名算法:,
//单个注销URL AD FS
注销URL:,
//单个注销回调URL
logoutCallbackUrl:``,
}
但经过大量研究,我意识到这种身份验证:windows选项是罪魁祸首,因此我将其改为:
{
// URL that should be configured inside the AD FS as return URL for authentication requests
callbackUrl: `<URL>`,
// URL on which the AD FS should be reached
entryPoint: <URL>,
// Identifier for the CIR-COO application in the AD FS
issuer: <identifier>,
identifierFormat: null,
// CIR-COO private certificate
privateCert: <private_cert_path>,
// Identity Provider's public key
cert: <cert_path>,
authnContext: ["urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
"urn:federation:authentication:windows"],
// AD FS signature hash algorithm with which the response is encrypted
signatureAlgorithm: <algorithm>,
// Single Log Out URL AD FS
logoutUrl: <URL>,
// Single Log Out callback URL
logoutCallbackUrl: `<URL>`,
},
{
//应在AD FS中配置为身份验证请求返回URL的URL
callbackUrl:``,
//应在其上访问AD FS的URL
入口点:,
//AD FS中CIR-COO应用程序的标识符
发行人:,
地址:null,
//CIR-COO专用证书
私人证书:,
//身份提供者的公钥
证书:,
authnContext:[“urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”,
“urn:federation:authentication:windows”],
//用于加密响应的AD FS签名哈希算法
签名算法:,
//单个注销URL AD FS
注销URL:,
//单个注销回调URL
logoutCallbackUrl:``,
},
这基本上意味着它不会检索默认登录到系统的用户的Windows凭据,从而重定向到ADFS服务器的登录屏幕。因此,经过大量研究和调查,我确实找到了解决此问题的方法。 诀窍在于passport saml包的定义,特别是authncontext参数 因此,之前我将SamlStrategy选项定义为:
{
// URL that should be configured inside the AD FS as return URL for authentication requests
callbackUrl: `<URL>`,
// URL on which the AD FS should be reached
entryPoint: <URL>,
// Identifier for the CIR-COO application in the AD FS
issuer: <identifier>,
identifierFormat: null,
// CIR-COO private certificate
privateCert: <private_cert_path>,
// Identity Provider's public key
cert: <cert_path>,
authnContext: ["urn:federation:authentication:windows"],
// AD FS signature hash algorithm with which the response is encrypted
signatureAlgorithm: <algorithm>,
// Single Log Out URL AD FS
logoutUrl: <URL>,
// Single Log Out callback URL
logoutCallbackUrl: `<URL>`,
}
{
//应在AD FS中配置为身份验证请求返回URL的URL
callbackUrl:``,
//应在其上访问AD FS的URL
入口点:,
//AD FS中CIR-COO应用程序的标识符
发行人:,
地址:null,
//CIR-COO专用证书
私人证书:,
//身份提供者的公钥
证书:,
authnContext:[“urn:federation:authentication:windows”],
//用于加密响应的AD FS签名哈希算法
签名算法:,
//单个注销URL AD FS
注销URL:,
//单个注销回调URL
logoutCallbackUrl:``,
}
但经过大量研究,我意识到这种身份验证:windows选项是罪魁祸首,因此我将其改为:
{
// URL that should be configured inside the AD FS as return URL for authentication requests
callbackUrl: `<URL>`,
// URL on which the AD FS should be reached
entryPoint: <URL>,
// Identifier for the CIR-COO application in the AD FS
issuer: <identifier>,
identifierFormat: null,
// CIR-COO private certificate
privateCert: <private_cert_path>,
// Identity Provider's public key
cert: <cert_path>,
authnContext: ["urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport",
"urn:federation:authentication:windows"],
// AD FS signature hash algorithm with which the response is encrypted
signatureAlgorithm: <algorithm>,
// Single Log Out URL AD FS
logoutUrl: <URL>,
// Single Log Out callback URL
logoutCallbackUrl: `<URL>`,
},
{
//应在AD FS中配置为身份验证请求返回URL的URL
callbackUrl:``,
//应在其上访问AD FS的URL
入口点:,
//AD FS中CIR-COO应用程序的标识符
发行人:,
地址:null,
//CIR-COO专用证书
私人证书:,
//身份提供者的公钥
证书:,
authnContext:[“urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”,
“urn:federation:authentication:windows”],
//用于加密响应的AD FS签名哈希算法
签名算法:,
//单个注销URL AD FS
注销URL:,
//单个注销回调URL
logoutCallbackUrl:``,
},
这基本上意味着它不会检索默认登录到系统的用户的Windows凭据,从而重定向到ADFS服务器的登录屏幕。使用authnContext:[“urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport”]在会话中,安装程序将在注销后再次显示用户名和密码页面
已注销https://adfs-url/adfs/ls/?wa=wsignout1.0.
再次登录后将创建新会话id。使用authnContext: