title: Can't read session data in policy AuthorizationHandler
body: <p>Using .NET Core 1.1, I've created an AuthorizationHandler:</p>
  
  <pre><code>public class HasStoreAccountAuthorizationHandler : AuthorizationHandler&lt;HasStoreAccountRequirement&gt;
  {
      private SessionHelper SessionHelper { get; }
  
      public HasStoreAccountAuthorizationHandler(SessionHelper sessionHelper)
      {
          this.SessionHelper = sessionHelper;
      }
  
      protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasStoreAccountRequirement requirement)
      {
          if (this.SessionHelper?.Accounts != null &amp;&amp; this.SessionHelper.Accounts.Any()) context.Succeed(requirement);
          return Task.FromResult(0);
      }
  }
  </code></pre>
  
  <p>And I have a SessionHelper class which serializes non-primitive values into session: </p>
  
  <pre><code>public class SessionHelper
  {
      public IEnumerable&lt;AccountInformation&gt; Accounts
      {
          get =&gt; this.Session.Get&lt;IEnumerable&lt;AccountInformation&gt;&gt;(AccountsKey);
          set =&gt; this.Session.Set&lt;IEnumerable&lt;AccountInformation&gt;&gt;(AccountsKey, value);
      }
  
      public static class SessionHelperExtensionMethods
      {
          public static void Set&lt;T&gt;(this ISession session, string key, T value)
          {
              session.SetString(key, JsonConvert.SerializeObject(value));
          }
  
          public static T Get&lt;T&gt;(this ISession session, string key)
          {
              var value = session.GetString(key);
              return value == null ? default(T) : JsonConvert.DeserializeObject&lt;T&gt;(value);
          }
      }
  }
  </code></pre>
  
  <p>Accessing SessionHelper.Accounts anywhere else in the code works fine. However, whenever the policy AuthorizationHandler is called, the following error is thrown:</p>
  
  <pre><code>An exception was thrown while deserializing the token.
  System.InvalidOperationException: The antiforgery token could not be decrypted.
  ---&gt; System.Security.Cryptography.CryptographicException: The key {KEYNAME} was not found in the key ring.
  at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus&amp; status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean&amp; requiresMigration, Boolean&amp; wasRevoked) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) --- End of inner exception stack trace --- at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext) System.Security.Cryptography.CryptographicException: The key {KEYNAME} was not found in the key ring.
  at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus&amp; status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean&amp; requiresMigration, Boolean&amp; wasRevoked) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
  </code></pre>
  
  <p>The web site machine key is set in the web.config and IIS,using SHA1/AES with both "Generate a unique key for each application" checked and unchecked (e.g., "KEY_VALUE,IsolateApps" and "KEY_VALUE").</p>
  
  <p>I've also created a data protection registry hive <em>and</em> configured the IIS app pool to load the user profile per this <a href="https://docs.microsoft.com/en-us/aspnet/core/publishing/iis#data-protection" rel="nofollow noreferrer">link</a>.</p>
  
  <p>I've also added data protection in Startup.cs (with various lines added/removed):</p>
  
  <pre><code>services.AddAntiforgery();
  services.AddDataProtection()
          .SetApplicationName("APPNAME")
          .SetDefaultKeyLifetime(TimeSpan.FromDays(365))
          .PersistKeysToFileSystem(new DirectoryInfo(Configuration["DataProtection:LocalPaths:KeyLocation"]));
  </code></pre>
  
  <p>In some cases, SessionHelper.Accounts is read correctly and no exception is thrown. However, once the app recycles, eventually SessionHelper.Accounts is null and the exception is thrown. Logging out of the system and logging in again has no effect on error.</p>
  
  <p>Thoughts?</p>