我的网站是基于WIF的自定义STS的依赖方。我们最近实现了一个安全令牌缓存,如下所述:Azure/web-farm ready SecurityTokenCache。我们的实现与该链接中描述的实现之间的主要区别在于,我们使用Azure AppFabric缓存作为持久缓存的后备存储,而不是表存储。这有助于减轻我们在某些浏览器上的令牌截断问题,但引入了一个新问题(我们看到截断问题主要是在除了fedauth cookie之外还有谷歌分析+防伪cookie的页面上)。我们现在每天都会收到几千次以下异常:
System.IdentityModel.Tokens.SecurityTokenException
ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context.
System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context.
at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver)
at Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie)
at Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken)
at Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
此异常似乎发生在重定向循环中,因此我们会在1-2分钟的时间内看到数百个异常。
在研究异常时,我无法找到任何有用的信息。到目前为止唯一有希望的金块是有人提到它可能与会话之前到期的缓存对象有关。
我们无法在内部重现问题,只知道它存在,因为数千个条目填满了我们的Elmah表。非常感谢任何帮助或见解。
我们推出了我们认为可能有助于解决问题的方法(下面的代码),但它没有效果:
HttpContext.Current.Response.Cookies.Remove("FedAuth");
WSFederationAuthenticationModule authModule = FederatedAuthentication.WSFederationAuthenticationModule;
string signoutUrl = (WSFederationAuthenticationModule.GetFederationPassiveSignOutUrl(authModule.Issuer, authModule.Realm, null));
Response.Redirect(signoutUrl);
答案 0 :(得分:6)
我有一个MVC单页面应用程序作为依赖方使用WSO2 4.5作为IDP并且得到了同样的错误 - " System.IdentityModel.Tokens.SecurityTokenException ID4243:无法创建SecurityToken。在令牌缓存中找不到令牌,并且在上下文中未找到cookie。 ..."做了一次搜索,发现了以下由Thinktecture成名的Brock Allen发表的声明。
当浏览器发送包含用户声明的cookie时会抛出此异常,但无法执行某些处理(密钥已更改,因此无法验证令牌或使用服务器端缓存)并且缓存为空)。最终用户无法对此做很多事情,他们将继续收到错误,因为浏览器会继续发送cookie。
完整文章:http://brockallen.com/2012/10/22/dealing-with-session-token-exceptions-with-wif-in-asp-net/
在同一篇文章中,他提供了以下代码片段,解决了我的问题。在Global.asax中:
void Application_OnError()
{
var ex = Context.Error;
if (ex is SecurityTokenException)
{
Context.ClearError();
if (FederatedAuthentication.SessionAuthenticationModule != null)
{
FederatedAuthentication.SessionAuthenticationModule.SignOut();
}
Response.Redirect("~/");
}
}
答案 1 :(得分:2)
缓存SessionSecurityToken导致此问题。缓存目标位于应用程序池的本地域中,因此当.NET需要内存时,它将自动被清除。最好的解决方案是两个取消缓存以确保安全性,或实现自己的子系统进行缓存。
适用于Windows Server的AppFabric memcached - 分布式内存对象缓存系统
var sessionSecurityToken = new SessionSecurityToken(principal, TimeSpan.FromHours(Convert.ToInt32(System.Web.Configuration.WebConfigurationManager.AppSettings["SessionSecurityTokenLifeTime"])))
{
IsPersistent = false, // Make persistent
IsReferenceMode = true // Cache on server
};
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
答案 2 :(得分:1)
如果您浏览到刚刚启动的应用程序,我们会看到这个确切的错误,而您的浏览器仍然保留了早期会话中的cookie。由于这些cookie是会话cookie,修复方法是关闭所有浏览器窗口并再次浏览应用程序。
据我所知,我们的应用程序是使用WIF重定向到AD FS的“普通”Web应用程序,没有任何特殊的安全令牌缓存。但是,我们对WIF cookie使用“会话模式”(例如参见"Your FedAuth Cookies on a Diet: IsSessionMode=true"),这使得WIF cookie变得更小。
答案 3 :(得分:1)
我们目前面临着完全相同的问题,尽管我们的情况有点不同。我们正在尝试使用WIF为Outlook Web App(OWA)提供Shibboleth SSO。我们在负载均衡器后面有几个OWA主机。
WIF生成的FedAuth cookie(和FedAuth1)大小超过2.5 kB。我们的负载均衡器会截断cookie。所以我们在OWA的global.asax文件中将 IsSessionMode -Property设置为 true 。现在,cookie大小减少到大约。 600字节,这很好。 OWA工作。
但是,在同一台服务器上运行的Exchange控制面板(ECP)不再起作用。 ECP在同一IIS应用程序池中运行,并且还在其global.asax文件中设置了IsSessiobnMode-Property。无论何时调用ECP,应用程序都不会发回任何响应,但WIF报告:
Current user: 'User not set'
Request for URL 'http://owa.ourdomain.com/ecp/' failed with the following error:
System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context.
答案 4 :(得分:0)
如果令牌中的声明数量或令牌的总大小太大而无法在Cookie中来回传输,则应执行此操作。如果不是这样,那么简化您的解决方案,只使用使用cookie的默认设置。但是,你应该使用基于证书的cookie加密,因此它仍然是“农场友好的”。默认情况下,WIF将使用具有机器关联性的DPAPI进行加密。