zoukankan      html  css  js  c++  java
  • DataProtection设置问题引起不同ASP.NET Core站点无法共享用户验证Cookie

    这是这两天ASP.NET Core迁移中遇到的一个问题。2个ASP.NET Core站点(对应于2个不同的ASP.NET Core Web应用程序),2个站点都可以登录,但在其中任1个站点登录后,在当前站点处于登录状态,访问另外1个站点却处于未登录状态。

    开始以为是CookieAuthenticationOptions的设置不一致引起的,检查代码后确认AuthenticationScheme,CookieName,CookieDomain都是一样的。

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        CookieName = ".AspNetCore.Cookies",
        CookieDomain = ".cnblogs.com"
    });

    (AuthenticationScheme的默认值是"Cookies")

    之后怀疑是DataProtection的密钥不一致引起的,我们用的是同一个阿里云redis实例存储密钥,存储方式上不会造成不一致。

    if (Environment.IsDevelopment())
    {
        services.AddDistributedMemoryCache();
    }
    else
    {
        services.AddDistributedServiceStackRedisCache(options =>
        {
            Configuration.GetSection("redis").Bind(options);
            //Workaround for deadlock when resolving host name
            IPAddress ip;
            if (!IPAddress.TryParse(options.Host, out ip))
            {
                options.Host = Dns.GetHostAddressesAsync(options.Host)
                .Result.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork).ToString();
            }
        });
    }
    services.AddDataProtection().PersistKeysToDistributedStore();

    为了进一步确认密钥是否是一样的,修改了 DataProtection.DistributedStore 的源代码将密钥打印在控制台,运行后确认2个站点用的密钥是一样的。

    public IReadOnlyCollection<XElement> GetAllElements()
    {
        var data = _cache.GetString(_key);
        Console.WriteLine(data);
        if (!string.IsNullOrEmpty(data))
        {
            return XDocument.Parse(data).Root.Elements().ToList().AsReadOnly();
        }
        else
        {
            return new List<XElement>().AsReadOnly();
        }
    }

    后来突然想到 services.AddDataProtection() 是不是有什么配置选项?F12之后发现果然有个DataProtectionOptions:

    public static IDataProtectionBuilder AddDataProtection(this IServiceCollection services, Action<DataProtectionOptions> setupAction);

    继续F12发现DataProtectionOptions只有1个属性ApplicationDiscriminator,点开它的注释后,问题的答案跃然而出:

    //
    // Summary:
    //     Provides global options for the Data Protection system.
    public class DataProtectionOptions
    {
        public DataProtectionOptions();
    
        //
        // Summary:
        //     An identifier that uniquely discriminates this application from all other applications
        //     on the machine. The discriminator value is implicitly included in all protected
        //     payloads generated by the data protection system to isolate multiple logical
        //     applications that all happen to be using the same key material.
        //
        // Remarks:
        //     If two different applications need to share protected payloads, they should ensure
        //     that this property is set to the same value across both applications.
        public string ApplicationDiscriminator { get; set; }
    }

    原来不同的ASP.NET Core应用程序要使用同样的加解密方式,除了共享密钥,还要设置同样的ApplicationDiscriminator。

    添加如下的代码后问题立马解决。

    services.AddDataProtection(options => options.ApplicationDiscriminator = "cnblogs.com");
  • 相关阅读:
    ubuntu 制做samba
    《Programming WPF》翻译 第4章 前言
    《Programming WPF》翻译 第4章 3.绑定到数据列表
    《Programming WPF》翻译 第4章 4.数据源
    《Programming WPF》翻译 第5章 6.触发器
    《Programming WPF》翻译 第4章 2.数据绑定
    《Programming WPF》翻译 第4章 1.不使用数据绑定
    《Programming WPF》翻译 第5章 7.控件模板
    《Programming WPF》翻译 第5章 8.我们进行到哪里了?
    《Programming WPF》翻译 第5章 5.数据模板和样式
  • 原文地址:https://www.cnblogs.com/dudu/p/6495951.html
Copyright © 2011-2022 走看看