服务提供商不活动后的 SAML 2.0 单点注销最佳实践

SAML

了解会话超时后 SAML 2.0 单点注销

由于 SAML 2.0 单点登录 (SSO) 系统允许用户使用一组凭据登录各种应用程序,因此大大简化了用户身份验证。但是,单点注销 (SLO) 概念也存在重大问题,特别是当用户的会话由于尚未登录而在服务提供商 (SP) 处过期时会发生什么情况。在这种情况下,身份提供商是否应该(IDP)会话也结束了吗?

SP 和 IDP 之间的会话管理对于确保 SAML 2.0 环境中的安全高效访问至关重要。当 SP 会话结束时,用户是否仍应连接到 IDP 并不总是显而易见,这可能会对链接到同一 IDP 的其他应用程序产生影响。这引发了有关可用性和安全性的问题。

许多企业,特别是那些使用 Microsoft Entra 等界面的企业,都需要建立一个明确的最佳实践来处理这些会话超时。 SP 的会话只是在 SP 级别停止更好,还是还应该导致 SLO 将用户从其 IDP 帐户中注销?

本文使用真实示例来说明处理会话超时并保证安全性和可用性的最有效技术,并研究了在此类情况下处理 SAML 2.0 SLO 事件的标准实践和标准。

命令 使用示例
session() 在 Express 应用程序中用于控制用户会话。在示例中,它有助于监视用户活动和会话超时,以便可以在需要时触发注销逻辑。
maxAge 指定会话 cookie 有效的时间范围。在此实例中,计时器设置为在 600000 毫秒(即 10 分钟)后到期,并启动注销事件。
create_logout_request_url() 当服务提供商会话终止时,此 SAML2 库方法创建的单点注销 (SLO) 请求 URL 将转发到身份提供商 (IDP)。
readFileSync() 同步读取密钥文件和证书,这是设置 SAML2 服务提供程序所必需的。为了使服务提供商和身份提供商安全地通信,这些认证是必要的。
assert_endpoint 指示成功进行身份验证后,身份提供者将用于传输 SAML 断言的 URL。通过这样做,可以保证服务提供商级别的用户身份验证。
window.onload 此事件用于重置前端中的会话不活动计时器。它确保当用户第一次加载程序时,计时器重新启动。
onmousemove 为了重置会话计时器,此事件侦听器会检测任何鼠标移动。这对于密切关注用户行为并避免意外会话超时至关重要。
fetch() 用于在会话超时后向服务器异步发送 SLO 请求。为了与身份提供者连接并将用户从 IDP 中注销,它启动了后端逻辑。
setTimeout() 前端代码中的此函数会导致在预定的不活动时间后发生会话超时事件。这对于关注用户行为和实施安全法规至关重要。

使用 SAML 2.0 会话超时处理优化单点注销

使用 Express 是用于处理单点注销 (SLO) 的后端脚本,重点关注跟踪用户会话过期并在服务提供商 (SP) 和身份提供商 (IDP) 级别启动注销序列的功能。 Express 会话的管理是这一推理的核心。我们通过将会话设置为在预定的不活动时间(在我们的示例中为十分钟)后终止来建立触发点。当会话结束时,脚本使用 `create_logout_request_url()} 方法启动 SAML 2.0 注销请求,然后连接到 IDP(在本例中, ) 完全结束用户会话。这通过保证用户完全退出系统来增强安全性。

我们加载 并使用“readFileSync()}命令将密钥输入到应用程序中,以启用 SP (MyApp) 和 IDP (Microsoft Entra) 之间的安全通信。通过验证注销请求,这些证书可以防止非法注销并保证通信保持加密和确认。生成注销请求 URL 后,用户将被发送到该 URL,IDP 在此处理注销,并在需要时结束用户跨任何关联应用程序的会话。维护多应用程序单点登录 (SSO) 安装的安全性和完整性需要这种双向通信。

JavaScript 脚本对于在前端实时跟踪用户活动至关重要。每次用户与程序交互时,我们都会使用“onmousemove”和“onkeypress”等事件监听器重置会话超时。使用 setTimeout() 设置的计时器会提醒用户,并在用户空闲时自动将其从 SP (MyApp) 中注销。注销后,前面介绍的 SAML 2.0 注销过程由前端脚本使用“fetch()”向后端发送 SLO 请求来启动。该技术可确保及时、安全、无故障地解决 SP 级别的不活动问题。

当 SAML 2.0 集成和 结合起来,用户体验是无缝的,并且安全标准得到维护。为了防止用户保持身份验证的时间超过不活动期间允许的时间,会话超时会启动本地 SP 注销和 IDP 注销。尽管 SAML 2.0 不要求在会话超时方面采取任何特定行为,但使用会话过期来启动 SLO 被普遍认为是最佳实践。通过结束空闲会话,它可以在各种 SSO 连接平台上实现同步注销,从而在安全性和用户体验之间取得平衡。

使用 Node.js 和 Express 处理 SAML 2.0 单点注销和会话超时

利用 Node.js 和 Express 管理具有服务提供商会话超时的 SAML 2.0 SLO 的后端方法。此解决方案使用 SAML 请求来检查会话是否已过期并在身份提供商级别启动 SLO。

// Required modules for Node.js and SAML SSO
const express = require('express');
const session = require('express-session');
const saml2 = require('saml2-js');
const app = express();

// Service Provider (SP) setup
const sp = new saml2.ServiceProvider({
  entity_id: "http://myapp.com/metadata.xml",
  private_key: fs.readFileSync("./cert/sp-private-key.pem").toString(),
  certificate: fs.readFileSync("./cert/sp-certificate.pem").toString(),
  assert_endpoint: "http://myapp.com/assert"
});

// Identity Provider (IDP) setup
const idp = new saml2.IdentityProvider({
  sso_login_url: "https://login.microsoftonline.com/sso",
  sso_logout_url: "https://login.microsoftonline.com/logout",
  certificates: fs.readFileSync("./cert/idp-certificate.pem").toString()
});

// Session management
app.use(session({
  secret: 'mySecretKey',
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 600000 } // Set session expiration time
}));

// Middleware to handle session timeout and SLO
app.use((req, res, next) => {
  if (req.session.expires && Date.now() > req.session.expires) {
    sp.create_logout_request_url(idp, {}, (err, logout_url) => {
      if (err) return res.status(500).send("Logout error");
      return res.redirect(logout_url); // Trigger SLO
    });
  } else {
    next(); // Continue if session is valid
  }
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});

使用 JavaScript 前端和空闲超时检测来处理 SAML 2.0 SLO

在前端方法中,通过利用普通 JavaScript 来监视用户不活动并启动单点注销 (SLO) 来检测会话超时。这告诉服务提供商向身份提供商发出 SLO 请求。

// Define variables for session timeout
let timeoutDuration = 600000; // 10 minutes
let timeoutTimer;

// Reset the timer on any user interaction
function resetTimer() {
  clearTimeout(timeoutTimer);
  timeoutTimer = setTimeout(triggerLogout, timeoutDuration);
}

// Trigger logout function
function triggerLogout() {
  alert("Session expired due to inactivity.");
  window.location.href = "/logout"; // Redirect to SP logout
}

// Monitor user actions
window.onload = resetTimer;
document.onmousemove = resetTimer;
document.onkeypress = resetTimer;

// SLO event triggered after logout
function sendSLORequest() {
  fetch('/api/slo', { method: 'POST' })
    .then(response => {
      if (response.ok) {
        console.log("SLO request sent to IDP");
      }
    })
    .catch(err => console.error("SLO request failed", err));
}

探索 SAML 2.0:单点注销和不活动超时

SAML 2.0 单点注销 (SLO) 如何解决 服务提供商 (SP) 级别的服务是需要管理的关键组件。尽管很明显,SP 处的手动注销也会导致身份提供商 (IDP) 注销,但不活动导致的会话超时会使问题变得复杂。 SAML 2.0 标准没有明确说明会话到期时应如何处理 SLO。然而,这确实允许采用可以改善用户体验和安全性的最佳实践。

例如,即使由于不活动而被 SP 拒之门外,通过 Microsoft Entra (IDP) 登录 MyApp 等应用程序的用户也经常保持 IDP 登录状态。如果用户认为自己已完全注销,而使用同一 SSO 的其他应用程序仍在运行,这可能会引发 。设置 SAML 会话管理以模拟 IDP 级别的 SP 超时事件并保证同步注销是降低此风险的一种方法。

前端代码对空闲检测技术的实现是另一个因素。开发人员可以通过使用用户活动的事件侦听器来预测不活动时间并在会话到期之前提醒用户。通过使用此功能,用户可以保持对其会话的控制并确保他们的会话 不连续运行。在 SSO 集成环境中,开发人员可以通过在这些因素之间取得平衡来保持安全性和用户舒适度。

  1. 当会话超时时,服务提供商级别会发生什么?
  2. 通常,当 SP 级别的会话超时时,用户会从程序中注销。不过,这取决于系统的设置方式,因为 SAML 2.0 规范不要求这会导致 IDP 出现 SLO。
  3. 身份提供商处的 SLO 是否应该由服务提供商会话超时触发?
  4. 该组织的政策对此进行管理。尽管 SAML 2.0 没有强制要求,但出于安全原因,许多人选择在 SP 会话结束时在 IDP 处启动 SLO。
  5. 当非活动会话结束时,如何实现 SLO?
  6. 会话过期可以通过后端机制检测到,然后启动一个 向 IDP 提出 SLO 请求的过程。
  7. 如何在前端检测会话不活动?
  8. 事件侦听器如 和 通常用于跟踪不活动状态,因为每次用户与应用程序交互时它们都会重置计时器。
  9. 注销 SP 后,打开 IDP 会话是否安全?
  10. 让 IDP 会话保持打开状态可能会产生安全风险,特别是当用户认为自己已完全签出时。建议设置 SLO 以复制 SP 会话过期。

维护 SSO 系统的安全性需要确保身份提供商和服务提供商同步其注销过程。尽管 SAML 2.0 没有强制规定如何处理会话超时,但许多企业都以统一的方式处理单点注销。

建议每次服务提供商会话因不活动而结束时发送 SLO 请求,以提高安全性。这可确保用户已注销身份提供商和应用程序,从而避免在许多平台上进行不必要的访问。

  1. 有关 SAML 2.0 和 Single Log Out 标准和指南的详细文档可以在官方文档中找到 OASIS SAML 2.0 核心规范
  2. 有关 Microsoft Entra 及其与 SSO 和 SLO 集成的深入了解,请参阅 Microsoft 官方文档: Azure Active Directory 和 SAML
  3. 示例中使用的 Node.js SAML 库以及会话管理技术可以在以下位置进一步探索: SAML2-js 库文档
  4. 要了解配置单点登录和会话管理的最佳实践,请访问以下文章: 单点登录最佳实践 通过 Auth0。