我在依赖方应用程序中实现了滑动会话,如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
}
}
我的问题:
else
子句是否适合放置重新认证逻辑?答案 0 :(得分:2)
我建议您在STS和RP上同步会话生存期。
您可以在STS上将会话生存期设置为10分钟,在RP上设置10分钟,并在RP上使用滑动会话方法。在10分钟不活动后,两个会话都将过期,并且应该要求用户重新进行身份验证。
如果你有多个RP,你可以实现一种从RP到STS的保持活动形式 - 例如在RP上的每个网页中从STS加载资源。每当在RP上加载页面时,将从STS加载保持活动资源 - 刷新STS会话。在不活动10分钟后,它们都会超时并且用户必须重新进行身份验证。
“来自STS的资源”可能意味着在不可见的iframe中加载的网页(Web窗体/ MVC)。重要的是它是一个托管处理程序,因此请求由ASP.NET处理。
至于你的问题,如果你同步会话的生命周期,那么他们会一起度过:
为了完整性,如果无法同步会话生存期,则可以在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
希望有所帮助!