WIF 滑动会话重新进行身份验证



我已经在我的信赖方应用程序中实现了滑动会话,如 WIF 4.5 的滑动会话中所述。就目前而言,这很好用,但有一个问题似乎没有人谈论。

正如链接的博客文章所指出的,当 RP 令牌过期时,下次发出请求时,将从 STS 重新颁发令牌。 当然,假设 STS 会话生存期比 RP 的会话生存期长,如果您正在实现滑动会话,几乎可以肯定是这种情况。

无论如何,这完全违背了滑动会话的全部意义。

似乎没有人谈论的是 RP 会话到期时该怎么做。我想要的是,如果 RP 会话超时(通常是因为有人离开办公桌 10 分钟),我的应用程序将重定向到 STS 登录页面,用户可以在其中重新进行身份验证,然后重定向回我请求的页面;或者可能是我提出请求时所在的页面。

我几乎可以肯定这是可能的,但我完全不知道它是如何完成的。

这是我来自global.asax的代码:

    private const int InactivityTimeout = 5; // minutes
    void SessionAuthenticationModule_SessionSecurityTokenReceived
        (object sender, SessionSecurityTokenReceivedEventArgs e)
    {
        var now = DateTime.UtcNow;
        var validFrom = e.SessionToken.ValidFrom;
        var validTo = e.SessionToken.ValidTo;
        double halfSpan = (validTo - validFrom).TotalMinutes/2;
        if (validFrom.AddMinutes(halfSpan) < now && now < validTo)
        {
            // add more time
            var sam = sender as SessionAuthenticationModule;
            e.SessionToken = sam.CreateSessionSecurityToken(
                e.SessionToken.ClaimsPrincipal,
                e.SessionToken.Context,
                now,
                now.AddMinutes(InactivityTimeout),
                e.SessionToken.IsPersistent);
            e.ReissueCookie = true;
        }
        else
        {
            // re-authenticate with STS
        }
    }

我的问题:

  1. else子句是否是放置重新身份验证逻辑的适当位置?
  2. 如果是这样,请提供一个例子,因为我不知道。
  3. 如果#1的答案是否定的,那么我需要订阅一个单独的事件来告诉我"嘿,您的会话安全令牌已过期!

我建议您同步 STS 和 RP 上的会话生存期。

您可以在 STS 上将会话生存期设置为 10 分钟,在 RP 上设置为 10 分钟,并在 RP 上使用滑动会话方法。处于非活动状态 10 分钟后,两个会话都将过期,应要求用户重新进行身份验证。

如果您有多个 RP,则可以实现一种从 RP 到 STS 的保持活动形式 - 例如,在 RP 的每个网页中从 STS 加载资源。 每当在 RP 上加载页面时,都会从 STS 加载保持活动状态资源 - 刷新 STS 会话。在 10 分钟不活动后,它们都会超时,用户必须重新进行身份验证。

"来自 STS 的资源"可能意味着在不可见的 iframe 中加载的网页(Web 窗体/MVC)。重要的是它是一个托管处理程序,因此请求由 ASP.NET 处理。

至于您的问题,如果您同步会话生存期以便它们一起超时:

  1. 不,不需要在 else 子句中添加任何代码。如果令牌已过期,WIF 将重定向到 STS。
  2. 只需删除 else 子句即可。
  3. 让WIF为您处理这个问题。

为完整起见,如果无法同步会话生存期,可以在 RP 会话过期时触发联合注销。以下代码片段在配置的颁发者 (STS) 上触发注销。您可以将其放在 else 子句中,以便在 RP 会话过期后触发第一个请求的注销:

using System.IdentityModel.Services; //WIF 4.5
var stsAddress = new Uri(FederatedAuthentication.FederationConfiguration.WsFederationConfiguration.Issuer);
WSFederationAuthenticationModule.FederatedSignOut(stsAddress, null); //Optional replyUrl set to null

希望对您有所帮助!

相关内容

最新更新