• 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");
  • 相关阅读:
    JAVA下使用 连接sqlserver 驱动包
    Windows 7 、Windows Server 2008 和 Windows Server 2008 R2 的支持结束
    VBoxManage命令详解
    端口扫描之王——nmap入门精讲
    rehat-server7常见服务安装与配置总结
    mysql的安装和密码管理、mysql初始密码查找、密码修改、mysql登录
    vim常用命令总结 (转)
    关于《Python绝技:运用Python成为顶级黑客》的学习笔记
    常用MySQL图形化管理工具
    Chrome谷歌浏览器离线安装包下载
  • 原文地址:https://www.cnblogs.com/dudu/p/6495951.html
Copyright © 2020-2023  润新知