zoukankan      html  css  js  c++  java
  • asp.net core session丢失问题排查

           最近公司采用asp.net core的站点在外测环境中,总是发现存在session丢失的情况。排查了好久,客户端.AspNetCore.Session的cookie未丢失,session的分布式缓存采用的redis主从复制也未发现问题,也想用cookie的变通解决方案,但是没解决根本问题,总是觉得如鱼梗在喉的不爽。后来在排查的过程中,发现同一个客户端通过nginx居然有时候会负载到不同的网站服务器上,检查过nginx,是通过ip_hash进行转发的啊,迷惑不解之际,公司的运维一语破的,原来公司是采用双线路由器的。于是猜测,是否因为存储cookie加密的key存在不同服务器上所导致。

           打开微软的Session的源码,先查看SessionMiddleware中间件的代码,其中有以下的关键源码:

    var cookieValue = context.Request.Cookies[_options.CookieName];
                var sessionKey = CookieProtection.Unprotect(_dataProtector, cookieValue, _logger);
                if (string.IsNullOrWhiteSpace(sessionKey) || sessionKey.Length != SessionKeyLength)
                {
                    // No valid cookie, new session.
                    var guidBytes = new byte[16];
                    CryptoRandom.GetBytes(guidBytes);
                    sessionKey = new Guid(guidBytes).ToString();
                    cookieValue = CookieProtection.Protect(_dataProtector, sessionKey);
                    var establisher = new SessionEstablisher(context, cookieValue, _options);
                    tryEstablishSession = establisher.TryEstablishSession;
                    isNewSessionKey = true;
                }
    sessionKey是从客户端的cookie中解密出来的,其中CookieProtection的_dataProtector来自
    _dataProtector = dataProtectionProvider.CreateProtector(nameof(SessionMiddleware));
    将系统默认注入的IDataProtectionProvider扒出来:

    发现IDataProtectionProvider为Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider,该IDataProtectionProvider的keyManager为
    Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager。


    果然不出所料,key存在单机上,打开微软的DataProtection-dev源码查看FileSystemXmlRepository中获取Key存储路径的实现:

    眼尖的发现项目下面就有一个将key持久化到redis的实现:

    添加相应的nuget包,修改ConfigureServices方法:
                services.AddDataProtection()
                    .PersistKeysToRedis(ConnectionMultiplexer.Connect(redisConnection), dataProtectionKey);
    终于完美解决!在采用分布式存储session的时候,最好将dataProtectionProvider的key也进行共享,否则如果做了ip_hash负载均衡,客户端ip一变,可能负载到另外一台服务器,导致存储session的cookie数据解密不出来从而获取不到session!
  • 相关阅读:
    拖动内容,滚动条滚动,横向
    前端面试题及答案整理(一)
    微软拼音转换工具类ChnCharInfo.dll
    table表格,让thead固定,tbody有滚动条,关键是都对齐的纯css写法。
    [C#]_[使用微软OpenXmlSDK (OpenXmlReader)读取xlsx表格] 读取大数据量100万条数据Excel文件解决方案
    asp.net mvc Post上传文件大小限制
    .net OADate 转javascript的Datetime js 5位 日期 转换
    在.NET开发中的单元测试工具之(1)——NUnit
    在.NET开发中的单元测试工具之(2)——xUnit.Net
    Git 头像修改 原
  • 原文地址:https://www.cnblogs.com/focus-lei/p/7714981.html
Copyright © 2011-2022 走看看