Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server Asp.Net Core SessionKey与SessionId不同的设计原因是什么? 一些背景_Sql Server_Security_Session_Cookies_Asp.net Core Mvc - Fatal编程技术网

Sql server Asp.Net Core SessionKey与SessionId不同的设计原因是什么? 一些背景

Sql server Asp.Net Core SessionKey与SessionId不同的设计原因是什么? 一些背景,sql-server,security,session,cookies,asp.net-core-mvc,Sql Server,Security,Session,Cookies,Asp.net Core Mvc,在asp.net core中,当使用SqlServer存储会话时,SqlServer表中的Id列被设置为sessionKey的值,这是由。我说得很奇怪,因为有一个SessionId,但表中的Id没有设置为该值,而是设置为SessionKey。(这不是我编造的) 该sessionKey用于表中的Id,也是加密并放置在会话cookie中的值。下面是SessionMiddlewarecode: var guidBytes = new byte[16]; CryptoRandom.GetBytes(

在asp.net core中,当使用SqlServer存储会话时,SqlServer表中的
Id
列被设置为
sessionKey
的值,这是由。我说得很奇怪,因为有一个
SessionId
,但表中的
Id
没有设置为该值,而是设置为
SessionKey
。(这不是我编造的)

sessionKey
用于表中的
Id
,也是加密并放置在会话cookie中的值。下面是
SessionMiddleware
code:

 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;
但是,
SessionId
是由以下代码行中的生成的
Guid

_sessionId = new Guid(IdBytes).ToString();
有趣的是,
ISession
接口为
SessionId
提供了一个属性,而不是
SessionKey
。因此,在代码中,访问
SessionId
通常比访问
SessionKey
容易得多,例如,当您可以访问
HttpContext
对象时

如果希望这样做,则很难将会话与数据库记录进行匹配。stackoverflow上的另一个用户也注意到了这一点

为什么?
我想知道的是为什么系统是这样设计的?为什么
SessionId
SessionKey
不是同一个?为什么要使用两种不同的
guid
?我之所以这样做,是因为我正在创建自己的
ISession
实现,而且我很想在实现中使用
SessionKey
作为
SessionId
,以便更容易地将数据库中的记录与会话相匹配。这是个坏主意吗?为什么wan不以这种方式设计DistributedSession对象,而不是生成一个与SessionKey不同的SessionId?我能想到的唯一原因可能是试图通过混淆数据库记录与其所属会话之间的链接来提高安全性。但一般来说,安全专业人员并不认为通过模糊处理实现安全性是有效的。所以我想知道为什么要实施这样的设计?

我也在GitHub上发布了这个问题,试图得到答案

@Tratcher在这里回答了这个问题,所以我把他的答案贴在下面,这样它也可以在stackoveflow上找到

生命是不同的。会话(和SessionId)的真实生存期由服务器控制。SessionKey存储在cookie中,并在客户端上存在不确定的时间。如果会话在服务器上过期,然后客户端使用旧SessionKey发送一个新请求,则会创建一个新会话实例,该实例使用新SessionId,但使用旧SessionKey存储,这样我们就不必发出新cookie


换句话说,不要依赖于你无法控制的事情。客户端可以无限期地保留和重播他们的会话密钥,但由服务器决定是否仍然是同一个会话。

以防有人需要在asp.net core 3中获取会话密钥

  • 为IDataProtector添加DI(重要!创建保护器时,它应该是nameof(SessionMiddleware))

  • 创建将为会话cookie获取正确值的方法

    private string Pad(string text)
    {
        var padding = 3 - ((text.Length + 3) % 4);
        if (padding == 0)
        {
            return text;
        }
        return text + new string('=', padding);
    }
    
  • 使用它

    public ActionResult TestSession(  )
    {
    
        var protectedText = HttpContext.Request.Cookies[ ".AspNetCore.Session" ];
    
        var sessionKey = "";
        var protectedData = Convert.FromBase64String(Pad(protectedText));
        if (protectedData == null)
        {
            sessionKey = string.Empty;
        }
    
        var userData = _dataProtector.Unprotect(protectedData);
        if (userData == null)
        {
            sessionKey = string.Empty;
        }
    
        sessionKey = Encoding.UTF8.GetString(userData);
    
        return Content( sessionKey );
    }
    
  • public ActionResult TestSession(  )
    {
    
        var protectedText = HttpContext.Request.Cookies[ ".AspNetCore.Session" ];
    
        var sessionKey = "";
        var protectedData = Convert.FromBase64String(Pad(protectedText));
        if (protectedData == null)
        {
            sessionKey = string.Empty;
        }
    
        var userData = _dataProtector.Unprotect(protectedData);
        if (userData == null)
        {
            sessionKey = string.Empty;
        }
    
        sessionKey = Encoding.UTF8.GetString(userData);
    
        return Content( sessionKey );
    }