2017-08-18 20 views
1

をセッションデータを読み取ることができません:は、私が作成した.NETのコア1.1を使用して、ポリシーでAuthorizationHandler AuthorizationHandler

public class HasStoreAccountAuthorizationHandler : AuthorizationHandler<HasStoreAccountRequirement> 
{ 
    private SessionHelper SessionHelper { get; } 

    public HasStoreAccountAuthorizationHandler(SessionHelper sessionHelper) 
    { 
     this.SessionHelper = sessionHelper; 
    } 

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasStoreAccountRequirement requirement) 
    { 
     if (this.SessionHelper?.Accounts != null && this.SessionHelper.Accounts.Any()) context.Succeed(requirement); 
     return Task.FromResult(0); 
    } 
} 

をそして私はセッションに非プリミティブな値をシリアライズSessionHelperをクラスがあります。

public class SessionHelper 
{ 
    public IEnumerable<AccountInformation> Accounts 
    { 
     get => this.Session.Get<IEnumerable<AccountInformation>>(AccountsKey); 
     set => this.Session.Set<IEnumerable<AccountInformation>>(AccountsKey, value); 
    } 

    public static class SessionHelperExtensionMethods 
    { 
     public static void Set<T>(this ISession session, string key, T value) 
     { 
      session.SetString(key, JsonConvert.SerializeObject(value)); 
     } 

     public static T Get<T>(this ISession session, string key) 
     { 
      var value = session.GetString(key); 
      return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value); 
     } 
    } 
} 

コード内の他の場所でSessionHelper.Accountsにアクセスすると正常に動作します。ポリシーAuthorizationHandlerが呼ばれるたびただし、次のエラーがスローされます。

An exception was thrown while deserializing the token. 
System.InvalidOperationException: The antiforgery token could not be decrypted. 
---> 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& status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& 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& status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) 

ウェブサイトのマシンキーは、「それぞれに固有のキーを生成し、両方でSHA1/AESを使用して、web.configファイルおよびIISに設定されています(例えば、 "KEY_VALUE、IsolateApps"、 "KEY_VALUE")をチェックし、チェックを外す。

データ保護レジストリハイブを作成して、IISアプリケーションプールをこのlinkのユーザープロファイルを読み込むように構成しました。 Startup.csで

私も追加したデータ保護(様々な線では、追加/削除):いくつかのケースでは

services.AddAntiforgery(); 
services.AddDataProtection() 
     .SetApplicationName("APPNAME") 
     .SetDefaultKeyLifetime(TimeSpan.FromDays(365)) 
     .PersistKeysToFileSystem(new DirectoryInfo(Configuration["DataProtection:LocalPaths:KeyLocation"])); 

は、SessionHelper.Accountsが正しく読み込まれ、例外がスローされません。しかし、アプリケーションがリサイクルすると、最終的にはSessionHelper.Accountsがnullになり、例外がスローされます。システムからログアウトして再度ログインしてもエラーには影響しません。

思考?

答えて

0

私は、IHttpContextAccessorコンテキストではなく、渡されたAuthorizationHandlerContextコンテキストを介してセッションデータにアクセスすることでこれを解決することができました。 SessionHelperをで

protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasStoreAccountRequirement requirement) 
{ 
    var accounts = SessionHelper.GetAccounts(this.Context.HttpContext); 
    if (accounts != null && accounts.Any()) context.Succeed(requirement); 
    return Task.FromResult(0); 
} 
:AuthorizationHandlerで

public static IEnumerable<AccountInformation> GetAccounts(HttpContext context) 
{ 
    return context.Session.Get<IEnumerable<AccountInformation>>(AccountsKey); 
} 

関連する問題