ADFS 新鲜度和会话滑动
ADFS freshness and session sliding
I have implemented session sliding using in my customehttphandler module.
我正在尝试实现会话滑动以及在共享同一 ADFS 服务器的多个网站上进行身份验证。
public void SessionAuthenticationModuleSessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
{
SessionSecurityToken token = e.SessionToken;
DateTime nowUtc = DateTime.UtcNow;
DateTime validFrom = token.ValidFrom;
DateTime validTo = token.ValidTo;
double totalMinutes = (validTo - validFrom).TotalMinutes;
double halfSpan = totalMinutes / 2;
SessionAuthenticationModule sam = sender as SessionAuthenticationModule;
if (validTo < nowUtc)
{
if (sam != null)
{
sam.DeleteSessionTokenCookie();
e.Cancel = true;
}
}
else if ((nowUtc - validFrom).TotalMinutes >= halfSpan)
{
SessionSecurityToken renewToken = sam.CreateSessionSecurityToken(
token.ClaimsPrincipal,
token.Context,
nowUtc,
nowUtc.AddMinutes(totalMinutes),
true);
e.SessionToken = renewToken;
e.ReissueCookie = true;
//db timestamp update
}
}
And SignedIn event
public void WSFederationAuthenticationModuleSignedIn(object sender, EventArgs e)
{
token = gettoken from cookie
if (token.ValidTo > DateTime.Now.ToUniversalTime())
{
//db insert for new login (assuming this will fire only once on actual login)
reissue token
}
}
Session timeout is mentioned in the my relying party application web config
<securityTokenHandlers>
<add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sessionTokenRequirement lifetime="0:02" />
</add>
</securityTokenHandlers>
Token Life time on ADFS I do not want to change which is greater than 2 minutes.
But issue is, after 2 minutes time out is not happening. It goes to SingedIn event becuase i assume it reissue token and then it calls session token received event so this condition (if (validTo < nowUtc)) never satisfy, how can i achieve timeout here? Freshness="0"achieves it but If i set Freshness="0" then I can not get authenticated by other website which are on same ADFS server. I want to be authenticated on other website as well if i have logged in one.
If I remove freshness="0" I can be authenticated without login on second website which is different application.
Why SignedIn is getting called before session token received and How can i achieve timeout in proper way and get authenticated in multiple website?
注意:我的 customeHttpHanlder 模块中有这些事件。它还有其他事件以及 PostAuthenticateRequest。
当您收到会话令牌时,您从 adfs 收到的令牌开始过期。完全过期后,需要刷新。
- 这是在从 adfs 获得准确信息(每次您想了解有关用户的信息时调用广告)和可行情况(签名令牌具有一定的有效性,我们相信该信息保持有效)。
令牌过期后,您需要返回到 adfs(因此出现登录事件)以从 adfs 获取新令牌。这个想法是一些信息可能在这两个令牌的发行之间发生了变化。
您可以在客户端(您的依赖方)实现滑动会话,但这没有什么意义(我会回过头来),因为您告诉自己令牌在另一个时期内有效。您相信自己,但令牌中的信息可能会不同步,这就是您始终需要返回 adfs 的原因。
如果您自己实现令牌的自动刷新,所有这些可能都有意义。这意味着您将当前令牌换成具有新有效期的新令牌。我想 adfs 可以做到这一点(但为此你需要活动场景)。代码不多,但正确设置可能很糟糕,我没有任何示例。
最后你需要问问自己是否值得这么麻烦。 WIF 将再次执行自动登录,并且域内的用户将自动登录。域外的用户可能必须在此处再次键入凭据。我不认为这是世界末日。
- 最后,我看到您使用了 Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler,这是旧的实现方式。 .Net 4.5 有更新的实现..
I have implemented session sliding using in my customehttphandler module.
我正在尝试实现会话滑动以及在共享同一 ADFS 服务器的多个网站上进行身份验证。
public void SessionAuthenticationModuleSessionSecurityTokenReceived(object sender, SessionSecurityTokenReceivedEventArgs e)
{
SessionSecurityToken token = e.SessionToken;
DateTime nowUtc = DateTime.UtcNow;
DateTime validFrom = token.ValidFrom;
DateTime validTo = token.ValidTo;
double totalMinutes = (validTo - validFrom).TotalMinutes;
double halfSpan = totalMinutes / 2;
SessionAuthenticationModule sam = sender as SessionAuthenticationModule;
if (validTo < nowUtc)
{
if (sam != null)
{
sam.DeleteSessionTokenCookie();
e.Cancel = true;
}
}
else if ((nowUtc - validFrom).TotalMinutes >= halfSpan)
{
SessionSecurityToken renewToken = sam.CreateSessionSecurityToken(
token.ClaimsPrincipal,
token.Context,
nowUtc,
nowUtc.AddMinutes(totalMinutes),
true);
e.SessionToken = renewToken;
e.ReissueCookie = true;
//db timestamp update
}
}
And SignedIn event
public void WSFederationAuthenticationModuleSignedIn(object sender, EventArgs e)
{
token = gettoken from cookie
if (token.ValidTo > DateTime.Now.ToUniversalTime())
{
//db insert for new login (assuming this will fire only once on actual login)
reissue token
}
}
Session timeout is mentioned in the my relying party application web config
<securityTokenHandlers>
<add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sessionTokenRequirement lifetime="0:02" />
</add>
</securityTokenHandlers>
Token Life time on ADFS I do not want to change which is greater than 2 minutes.
But issue is, after 2 minutes time out is not happening. It goes to SingedIn event becuase i assume it reissue token and then it calls session token received event so this condition (if (validTo < nowUtc)) never satisfy, how can i achieve timeout here? Freshness="0"achieves it but If i set Freshness="0" then I can not get authenticated by other website which are on same ADFS server. I want to be authenticated on other website as well if i have logged in one.
If I remove freshness="0" I can be authenticated without login on second website which is different application.
Why SignedIn is getting called before session token received and How can i achieve timeout in proper way and get authenticated in multiple website?
注意:我的 customeHttpHanlder 模块中有这些事件。它还有其他事件以及 PostAuthenticateRequest。
当您收到会话令牌时,您从 adfs 收到的令牌开始过期。完全过期后,需要刷新。
- 这是在从 adfs 获得准确信息(每次您想了解有关用户的信息时调用广告)和可行情况(签名令牌具有一定的有效性,我们相信该信息保持有效)。
令牌过期后,您需要返回到 adfs(因此出现登录事件)以从 adfs 获取新令牌。这个想法是一些信息可能在这两个令牌的发行之间发生了变化。
您可以在客户端(您的依赖方)实现滑动会话,但这没有什么意义(我会回过头来),因为您告诉自己令牌在另一个时期内有效。您相信自己,但令牌中的信息可能会不同步,这就是您始终需要返回 adfs 的原因。
如果您自己实现令牌的自动刷新,所有这些可能都有意义。这意味着您将当前令牌换成具有新有效期的新令牌。我想 adfs 可以做到这一点(但为此你需要活动场景)。代码不多,但正确设置可能很糟糕,我没有任何示例。
最后你需要问问自己是否值得这么麻烦。 WIF 将再次执行自动登录,并且域内的用户将自动登录。域外的用户可能必须在此处再次键入凭据。我不认为这是世界末日。
- 最后,我看到您使用了 Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler,这是旧的实现方式。 .Net 4.5 有更新的实现..