MachineKeySessionSecurityTokenHandler和会话令牌在应用程序重新启动之间到期

Chr*_*ons 7 claims-based-identity wif

在我的MVC应用程序中,我使用表单身份验证来验证用户,然后System.IdentityModel.Services.SessionAuthenticationModule继续会话.

虽然我还没有在这里有必要的时候,我也希望利用System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler这样应用程序将很好地住在一个Web场(由多米尼克·拜尔描述这里).

我遇到的问题是,鉴于基于machineKey的处理,我希望会话不仅可以从服务器机器到机器有效,而且还应该在应用程序重启后继续存在.但是,每当我重新启动或重建应用程序时,在浏览器中点击应用程序时,cookie显然会变为无效,我会被退回到身份验证屏幕.一旦再次验证,一切都很好,会话仍然存在.但是,下次应用程序重新启动或重建时,我不得不重新进行身份验证.

我确定这是WIF的一个方面,我没有得到,但我只是不知道从哪里转过来.我不怕延伸MachineKeySessionSecurityTokenHandler,但我想确保在我继续之前我理解这里发生了什么.我知道默认情况下SessionSecurityTokenHandler使用DPAPI结合应用程序池中的某些标识符进行加密,因此在这种情况下会发生这种情况,但这种行为MachineKeySessionSecurityTokenHandler让我感到困惑.应用程序中是否仍有一些标识符在重新启动时重新创建MachineKeySessionSecurityTokenHandler依赖?我只是错过了一个设置吗?

以下是我的web.config中的相关部分:

<configSections>
  <section name="system.identityModel"
           type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
Run Code Online (Sandbox Code Playgroud)

...

<system.identityModel>
  <identityConfiguration>
    <securityTokenHandlers>
      <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </securityTokenHandlers>
  </identityConfiguration>
</system.identityModel>
Run Code Online (Sandbox Code Playgroud)

...

<system.web>
  <machineKey compatibilityMode="Framework45"
              validationKey="E27893..."
              decryptionKey="ABC..." 
              validation="SHA1" decryption="AES" />
  <authentication mode="Forms">
  <forms loginUrl="~/Account/Login"
         timeout="10080" />
  </authentication>
</system.web>
Run Code Online (Sandbox Code Playgroud)

...

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="SessionAuthenticationModule"
         type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </modules>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

Chr*_*ons 0

好吧,这是我愚蠢的错误。由于与此处无关的原因,我将 FedAuth cookie 名称设置为非标准名称(即不是“ FedAuth”),如下所示:

FederatedAuthentication
  .FederationConfiguration
  .CookieHandler
  .Name = "SomeThingNotStandard";
Run Code Online (Sandbox Code Playgroud)

问题是我只是在成功登录时发出令牌时才这样设置。好吧,当然一切都会好起来的,因为现在内存中的配置正在寻找“SomeThingNotStandard”作为 cookie 名称。但是,在应用程序重新启动时,配置将恢复为默认值,查找“ FedAuth”,而不是“ SomeThingNotStandard”。这会强制重新登录,成功后,重新配置应用程序,然后一切看起来都很好。

因此,我将上面的代码放入其中Application_Start(),它在重新构建和重新启动时都可以正常工作。

我的举动很愚蠢。

编辑:

我将其移至配置

<system.identityModel.services>
  <federationConfiguration>
    <cookieHandler
      name="SomeThingNotStandard" />
  </federationConfiguration>
</system.identityModel.services>
Run Code Online (Sandbox Code Playgroud)