Asp.net mvc 4 声明的Windows身份验证MVC应用程序,多次调用身份验证并释放安全令牌cookie

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次+(我假设有些调用是并行/异步的)

我正在开发基于声明的MVC应用程序。我已经实现了IHttpModule(也称为“ClaimsTransformation Module”,它将身份转换为其他身份)和自定义ClaimsAuthenticationManager(它将其他声明添加到该身份),如下所示。页面加载,我可以检索新添加的声明,但没有什么严重问题

问题是:

  • 即使在初始页面加载我的自定义RomesClaimsAuthenticationManager.Authenticate方法也会被调用27次+(我假设有些调用是并行/异步的)
  • FedAuth(SessionToken)cookie检查永远不会返回true,即使在SAM(SessionAuthenticationManager)将SessionToken写入cookie之后——我可以看到它,但在下一次调用(仍在原始页面加载期间)它消失了——如果我打开其他页面,也会发生同样的事情
  • 自定义索赔认证经理:

    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)