首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法读取策略AuthorizationHandler中的会话数据

无法读取策略AuthorizationHandler中的会话数据
EN

Stack Overflow用户
提问于 2017-08-18 18:59:12
回答 1查看 1K关注 0票数 2

使用.NET Core1.1,我创建了一个AuthorizationHandler:

代码语言:javascript
复制
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类,它将非原始值序列化为会话:

代码语言:javascript
复制
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时,都会引发以下错误:

代码语言:javascript
复制
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)

网站机器密钥是在web.config和IIS中设置的,使用SHA1 1/AES,同时“为每个应用程序生成一个唯一的密钥”检查和未选中(例如,"KEY_VALUE,IsolateApps“和"KEY_VALUE")。

我还创建了一个数据保护注册表单元,并将IIS池配置为按此链接加载用户配置文件。

我还在Startup.cs中添加了数据保护(添加/删除了各种行):

代码语言:javascript
复制
services.AddAntiforgery();
services.AddDataProtection()
        .SetApplicationName("APPNAME")
        .SetDefaultKeyLifetime(TimeSpan.FromDays(365))
        .PersistKeysToFileSystem(new DirectoryInfo(Configuration["DataProtection:LocalPaths:KeyLocation"]));

在某些情况下,SessionHelper.Accounts被正确读取,没有异常被抛出。然而,一旦应用程序回收,最终SessionHelper.Accounts为null并引发异常。注销系统并再次登录不会影响错误。

有什么想法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-30 18:50:49

通过通过传递的AuthorizationHandlerContext上下文而不是IHttpContextAccessor上下文访问会话数据,我成功地修复了这个问题。

在SessionHelper中:

代码语言:javascript
复制
public static IEnumerable<AccountInformation> GetAccounts(HttpContext context)
{
    return context.Session.Get<IEnumerable<AccountInformation>>(AccountsKey);
}

在AuthorizationHandler中:

代码语言:javascript
复制
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);
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45763417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档