2012-03-20 184 views
11

我有一个网站是我们基于WIF的自定义STS的依赖方。我们最近实现了一个安全令牌缓存,如下所述:Azure/web-farm ready SecurityTokenCache。我们的实现和该链接中描述的实现之间的主要区别在于,我们使用Azure AppFabric缓存作为持久缓存的后备存储,而不是表存储。这有助于缓解我们在某些浏览器上出现令牌截断问题,但却引入了一个新问题(我们看到截断问题主要出现在除了fedauth cookie之外还包含Google Analytics(分析)+ antiforgery cookie的页面上)。我们现在会收到以下异常数千次,每天:WIF安全令牌缓存

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

这应该如果做令牌或的总规模索赔数量令牌太大而无法在Cookie中来回传送。如果情况并非如此,那么简化您的解决方案,并使用使用cookie的默认设置。然而,你可以使用基于证书的cookie加密,所以它仍然是“农场友好的”。默认情况下,WIF将使用具有机器亲和力的DPAPI进行加密。

+1

我们所实现的安全令牌缓存,因为我们的cookies的集体栈是超过某些浏览器(Safari浏览器,Opera等)的4096个字节的域cookie大小限制。它是为了响应cookie截断问题而实现的。我们也已经使用基于证书的cookie加密。安全令牌缓存对我们来说是“必须的”,并且具有我们希望的效果,但是实现已经创建了这个新的例外。这个异常的真正问题是它将我们的用户引入重定向循环。 – Jeff 2012-03-28 15:59:09

1

如果您浏览至新开始的应用程序,而您的浏览器仍然保留较早会话中的cookie,则会看到此确切错误。由于这些cookie是会话cookie,因此修复方法是关闭所有浏览器窗口并再次浏览到应用程序。

据我所知,我们的应用程序是一个'正常'的web应用程序,使用WIF重定向到AD FS,没有任何特殊的安全令牌缓存。但是,我们确实使用WIF cookie的“会话模式”(请参阅​​"Your FedAuth Cookies on a Diet: IsSessionMode=true"),这会使WIF Coo​​kie变得更小。

+0

那么,我们如何能够重现这一点,以确定如果这是问题,我们将如何防止它发生?我会检查,但我相信我们让浏览器坐在页面上24小时,然后刷新,看看我们是否可以得到它repro,它不会。我们是否还必须确保应用程序启动/重新启动?我不是100%确定你的意思是“新开始的应用程序”。 – 2012-04-02 03:47:16

1

我们目前面临完全相同的问题,虽然我们的情况有些不同。我们正在尝试使用WIF为Outlook Web App(OWA)提供Shibboleth SSO。负载均衡器后面有几台OWA主机。

WIF生成大小超过2.5 kB的FedAuth cookie(和FedAuth1)。我们的负载均衡器会截断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. 
2

引起缓存SessionSecurityToken此问题。缓存目标位于应用程序池的本地域,因此当.NET需要内存时,它将自动被清除。最好的解决方案是两个取消缓存安全或实现您自己的子系统进行缓存。

溶液1

的AppFabric的Windows Server 的memcached - 分布式内存对象缓存系统

解决方案2

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); 
5

我有一个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("~/"); 
    } 
}