您的位置:首页 > 编程语言 > ASP

DataProtection设置问题引起不同ASP.NET Core站点无法共享用户验证Cookie

2017-03-07 07:14 861 查看
这是这两天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");


原文地址:http://www.cnblogs.com/dudu/p/6495951.html
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐