7

我已经在我的依赖方应用程序中实现了滑动会话,如Sliding Sessions for 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 的答案是否定的,那么是否有一个我需要订阅的单独事件会告诉我“嘿,您的会话安全令牌已过期!”?
4

1 回答 1

2

我建议您在 STS 和 RP(s) 上同步会话生命周期。

您可以在 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

希望有帮助!

于 2013-09-16T19:31:57.737 回答