Asp.net mvc 4 声明的Windows身份验证MVC应用程序,多次调用身份验证并释放安全令牌cookie
我正在开发基于声明的MVC应用程序。我已经实现了IHttpModule(也称为“ClaimsTransformation Module”,它将身份转换为其他身份)和自定义ClaimsAuthenticationManager(它将其他声明添加到该身份),如下所示。页面加载,我可以检索新添加的声明,但没有什么严重问题 问题是:Asp.net mvc 4 声明的Windows身份验证MVC应用程序,多次调用身份验证并释放安全令牌cookie,asp.net-mvc-4,cookies,windows-authentication,claims,Asp.net Mvc 4,Cookies,Windows Authentication,Claims,我正在开发基于声明的MVC应用程序。我已经实现了IHttpModule(也称为“ClaimsTransformation Module”,它将身份转换为其他身份)和自定义ClaimsAuthenticationManager(它将其他声明添加到该身份),如下所示。页面加载,我可以检索新添加的声明,但没有什么严重问题 问题是: 即使在初始页面加载我的自定义RomesClaimsAuthenticationManager.Authenticate方法也会被调用27次+(我假设有些调用是并行/异步的)
public class RomesClaimsAuthenticationManager : ClaimsAuthenticationManager
{
// PROBLEM - THIS GETS HIT 27+ times on original page load
public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
{
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated == true)
{
((ClaimsIdentity)incomingPrincipal.Identity).AddClaim(new Claim(ClaimTypes.Email, "myTestEmail@email.com"));
// i will be making a db call here to get add'l user info from DB, and then convert it into claims
}
return incomingPrincipal;
}
}
Web.config文件:
<configSections>
<!--this is required for custom ClaimsAuthorizationManager-->
<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
<!--this will allow us to write ClaimsPrincipal to a cookie, saving from calls to db on each request-->
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
...
<system.identityModel>
<identityConfiguration>
<claimsAuthenticationManager type="ROMES.Admin.Security.RomesClaimsAuthenticationManager, ROMES.Admin" />
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandler mode="Default" requireSsl="true" />
</federationConfiguration>
</system.identityModel.services>
<system.web>
<authentication mode="Windows"/>
...
<authorization>
<allow roles="WINDOWS\ROMES_Admins"/>
<deny users="*" />
</authorization>
<!--must be in both here and system.webServer/modules-->
<!--see here WHY: https://msdn.microsoft.com/en-us/library/gg638734.aspx-->
<httpModules>
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</httpModules>
</system.web>
<system.webServer>
<!-- same as in system.web/httpModules-->
<modules>
<add name="RomesClaimsAuthorizationModule" type="ROMES.Admin.Security.RomesClaimsAuthorizationModule"/>
<!--this module will handle reading and writing cookie for identity/claims - so that there will be no need to call db every request for user info-->
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</modules>
...
</system.webServer>
...
...
...
我的主要问题是:
(1) 为什么我的身份验证块会被调用这么多次
(2) 为什么会话安全令牌cookie不能持久存在?这似乎是对资源的浪费。在这里
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies)
改为
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(context.Request.Cookie)
然后查看条件是否开始为真,代码是否返回
在David的评论后编辑:上下文被context.Request.Cookie替换了27次,因为页面上有26个资源?每次请求都会调用post auth,如果您的页面引用了一些静态资源,并且这些资源通过asp.net管道传输,则会收到其他请求。谢谢,@WiktorZychla。我想知道是否有一种方法可以让所有请求在第一次请求之后查看cookie或线程中的标识,以检查用户数据是否已加载。我也有同样的问题/顾虑,在第一次请求发出之前,使用ContainsSessionTokenCookie方法进行多个调用,您不能简单地将上下文用作参数,您必须指定一个cookiecollection@DavidThanx David。我想使用此行的上下文变量:
var context=((HttpApplication)sender.context代码>
FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(context.Request.Cookie)