2

我们正在使用 Windows Identity Foundation 为我们的应用程序实施单点登录解决方案。我遇到的问题是,当我认为 FedAuth cookie 应该在依赖方方面过期时,它并没有过期。

FedAuth cookie 直到其 ValidTo 时间后大约五分钟才会被销毁。出于测试目的,我将令牌生命周期和会话设置为十分钟后超时。

<sessionState timeout="10" mode="SQLServer" sqlConnectionString="..." />

<securityTokenHandlers>
  <add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
    <sessionTokenRequirement lifetime="00:10" />
  </add>
</securityTokenHandlers>  

我们已经实现了自己的 SessionAuthenticationModule,因为我们使用的是滑动会话。该代码几乎是从Programming Windows Identity Foundation中逐字获取的,但我认为这不是问题所在,因为我尝试在 SessionSecurityTokenReceived 事件中注释掉代码并且我看到了相同的行为,但只是为了完整性。

DateTime now = DateTime.UtcNow;
DateTime validFrom = e.SessionToken.ValidFrom;
DateTime validTo = e.SessionToken.ValidTo;

double tokenLifetime = (validTo - validFrom).TotalMinutes;

if( now < validTo && now > validFrom.AddMinutes( tokenLifetime / 2 ) )
{
    SessionAuthenticationModule sam = sender as SessionAuthenticationModule;
    e.SessionToken = sam.CreateSessionSecurityToken(
        e.SessionToken.ClaimsPrincipal, e.SessionToken.Context,
        now, now.AddMinutes( tokenLifetime ), e.SessionToken.IsPersistent );
    e.ReissueCookie = true;
}

如果我在上午 10:00 登录应用程序同时调试上述代码,我可以看到 validTo 值是上午 10:10。然后,我让应用程序等待 11 分钟,然后单击另一个链接。在调试上述内容时,我看到 now (10:11am) 的值确实 > validTo (10:10am) 因此令牌过期不会更新。在这一点上,我希望 SAM 销毁 FedAuth cookie。但是,FedAuth cookie 没有被破坏,Request.IsAuthenticated 的值仍然是 true(由于我假设的 cookie 的存在)并且用户继续访问应用程序。直到上午 10 点 15 分,我才真正看到 cookie 已过期(使用 Fiddler)。

我不知道为什么在validTo时间到期后第一次访问时FedAuth cookie没有被破坏。我可以通过将到期时间设置为比我真正想要的时间短五分钟来捏造它,但我更愿意理解为什么我会看到这种行为。

4

1 回答 1

3

发生这种情况是因为存在时钟偏差,默认情况下 I 设置为 5 分钟。通常,时钟偏差用于缓解服务器之间的时钟同步(在这种情况下是同一场的服务器)。如果您想禁用或减少该值,您可以通过设置(从我的头顶)来实现

FederatedAuthentication.ServiceConfiuration.MaxClockSkew = TimeSpan.FromSeconds(10);

只需确保服务器时钟 100% 同步

于 2012-09-28T13:59:27.527 回答