C# 为什么Session.Clear()-不';不行?

C# 为什么Session.Clear()-不';不行?,c#,asp.net-web-api,.net-core,.net-core-2.1,C#,Asp.net Web Api,.net Core,.net Core 2.1,我正在使用.NETCore2.1,并尝试将会话用作身份验证的一部分。我期望发生的是: 用户登录 我设置会话值 返回会话cookie 人员单击“注销” 我通过HttpContext.session.clear()清除会话 然后我试图假装会话cookie是从原始用户那里偷来的,因此我向服务器创建了另一个请求,并期望会话中设置的值不会出现。即使调用了Session.Clear(),它看起来仍然保持着它 代码: Startup.cs public void ConfigureServices(I

我正在使用
.NETCore2.1
,并尝试将会话用作身份验证的一部分。我期望发生的是:

  • 用户登录
  • 我设置会话值
  • 返回会话cookie
  • 人员单击“注销”
  • 我通过
    HttpContext.session.clear()清除会话
  • 然后我试图假装会话cookie是从原始用户那里偷来的,因此我向服务器创建了另一个请求,并期望会话中设置的值不会出现。即使调用了
    Session.Clear()
    ,它看起来仍然保持着它

    代码:

    Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {     
              services.AddSession(options =>
              {
                    options.IdleTimeout = TimeSpan.FromMinutes(10);
                    options.Cookie.Name = SessionCookieName;
                    options.Cookie.HttpOnly = true;
              });
        }
    
    
    
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.UseSession();
        }
    
    登录操作:

    HttpContext.Session.SetInt32(SessionConstants.Key, value);
    
    HttpContext.Session.Clear();
    
     var sessionValue = HttpContext.Session.GetInt32(SessionConstants.Key);
    
        var httpClientGenuineRequest = GetClient();
                    var httpClientAttacker = GetClient();
    
                    //Given
                    var request = new LoginRequest()
                    {
                       //filled properties
                    };
    
                    var loginResponse = await httpClientGenuineMember.PostAsync("urlToLoginAction", new JsonContent(request));
                    AddResponseCookiesToHeaders(httpClientAttacker, loginResponse);
    
                    await httpClientGenuineMember.PostAsync("urlToLogoutAction", new JsonContent(request));
    
                    //When
                    var response = await httpClientAttacker.GetAsync("urlToCheckStatusAction");
    
                    //Here the actual result is true
                    var actualResult = response.GetResult<bool>();
    
                    //Then
                    var expectedResult = false;
    
    注销操作:

    HttpContext.Session.SetInt32(SessionConstants.Key, value);
    
    HttpContext.Session.Clear();
    
     var sessionValue = HttpContext.Session.GetInt32(SessionConstants.Key);
    
        var httpClientGenuineRequest = GetClient();
                    var httpClientAttacker = GetClient();
    
                    //Given
                    var request = new LoginRequest()
                    {
                       //filled properties
                    };
    
                    var loginResponse = await httpClientGenuineMember.PostAsync("urlToLoginAction", new JsonContent(request));
                    AddResponseCookiesToHeaders(httpClientAttacker, loginResponse);
    
                    await httpClientGenuineMember.PostAsync("urlToLogoutAction", new JsonContent(request));
    
                    //When
                    var response = await httpClientAttacker.GetAsync("urlToCheckStatusAction");
    
                    //Here the actual result is true
                    var actualResult = response.GetResult<bool>();
    
                    //Then
                    var expectedResult = false;
    
    检查登录状态操作:

    HttpContext.Session.SetInt32(SessionConstants.Key, value);
    
    HttpContext.Session.Clear();
    
     var sessionValue = HttpContext.Session.GetInt32(SessionConstants.Key);
    
        var httpClientGenuineRequest = GetClient();
                    var httpClientAttacker = GetClient();
    
                    //Given
                    var request = new LoginRequest()
                    {
                       //filled properties
                    };
    
                    var loginResponse = await httpClientGenuineMember.PostAsync("urlToLoginAction", new JsonContent(request));
                    AddResponseCookiesToHeaders(httpClientAttacker, loginResponse);
    
                    await httpClientGenuineMember.PostAsync("urlToLogoutAction", new JsonContent(request));
    
                    //When
                    var response = await httpClientAttacker.GetAsync("urlToCheckStatusAction");
    
                    //Here the actual result is true
                    var actualResult = response.GetResult<bool>();
    
                    //Then
                    var expectedResult = false;
    
    发现问题的测试:

    HttpContext.Session.SetInt32(SessionConstants.Key, value);
    
    HttpContext.Session.Clear();
    
     var sessionValue = HttpContext.Session.GetInt32(SessionConstants.Key);
    
        var httpClientGenuineRequest = GetClient();
                    var httpClientAttacker = GetClient();
    
                    //Given
                    var request = new LoginRequest()
                    {
                       //filled properties
                    };
    
                    var loginResponse = await httpClientGenuineMember.PostAsync("urlToLoginAction", new JsonContent(request));
                    AddResponseCookiesToHeaders(httpClientAttacker, loginResponse);
    
                    await httpClientGenuineMember.PostAsync("urlToLogoutAction", new JsonContent(request));
    
                    //When
                    var response = await httpClientAttacker.GetAsync("urlToCheckStatusAction");
    
                    //Here the actual result is true
                    var actualResult = response.GetResult<bool>();
    
                    //Then
                    var expectedResult = false;
    
    但行为完全相同。

    原因是(听起来很荒谬),因为您没有清除正确的会话变量

    根据.net core 2.1中的会话,当以下两种情况之一发生时,会话结束:

    会话数据在实现时被删除 在会话到期时调用或

    然后,下列国家:

    没有默认机制通知应用程序代码客户端浏览器 已关闭或会话cookie在上被删除或过期 客户

    这告诉我们两件事:

    1)如果您想最大限度地使用过期的会话,您必须自己编写机制,在客户端会话过期或浏览器关闭时通知服务器。否则,即使浏览器关闭,您也有保留会话数据的风险(这是一种荒谬的情况,但确实存在)

    2)ISession.Clear方法是名称空间的一部分,这意味着当您调用
    HttpContext.Session.Clear()时您基本上什么也不清除。


    正如我所说,这种情况可能令人痛苦,但却是一个活生生的事实,如果我们选择使用.net core 2.1和会话状态,我们的代码必须知道如何处理这种情况。

    在挖掘代码后,我发现了问题:

    问题出在我的测试中。我将登录请求-响应cookies设置为“攻击者的”httpClient,而不是实际用户。结果,它没有得到
    会话Cookie
    ,因此我的
    会话.Clear()
    实际上清除了新创建的会话,而不是登录过程中创建的会话

    修正测试:

    var httpClientGenuineRequest = GetClient();
                    var httpClientAttacker = GetClient();
    
                    //Given
                    var request = new LoginRequest()
                    {
                       //filled properties
                    };
    
                    var loginResponse = await httpClientGenuineMember.PostAsync("urlToLoginAction", new JsonContent(request));
                    AddResponseCookiesToHeaders(httpClientGenuineMember, loginResponse); // THAT LINE MADE THE DIFFERENCE
                    AddResponseCookiesToHeaders(httpClientAttacker, loginResponse);
    
                    await httpClientGenuineMember.PostAsync("urlToLogoutAction", new JsonContent(request));
    
                    //When
                    var response = await httpClientAttacker.GetAsync("urlToCheckStatusAction");
    
                    //Here the actual result is true
                    var actualResult = response.GetResult<bool>();
    
                    //Then
                    var expectedResult = false;
    
    var httpClientGenuineRequest=GetClient();
    var httpClientAttacker=GetClient();
    //给定
    var请求=新登录请求()
    {
    //填充特性
    };
    var loginResponse=await-httpClientGenuineMember.PostAsync(“urlToLoginAction”,new-JsonContent(request));
    AddResponseCookiesToHeaders(httpClientGenuineMember,loginResponse);//那条线起了作用
    添加ResponseCookiestoHeader(httpClientAttacker、loginResponse);
    等待httpClientGenuineMember.PostAsync(“urlToLogoutAction”,新JsonContent(请求));
    //什么时候
    var response=await httpClientAttacker.GetAsync(“urlToCheckStatusAction”);
    //这里的实际结果是正确的
    var actualResult=response.GetResult();
    //然后
    var expectedResult=假;
    

    Session.Clear()
    完全按照预期工作。

    您使用哪个会话存储?(会话也可以完全存储在会话cookie中)这是默认行为吗?我不希望在浏览器关闭时清除会话,而是在用户单击站点上的注销按钮时清除会话。我认为,如果用户拥有会话Cookie,就足以找到正确的会话并将其清除。在常规的.NET中,这将由Session.about()实现。另外,如果我可以用用户在cookie中的Id除去会话中的值就足够了,因为代码会检查特定值是否在会话中。但是,您似乎没有得到正确的答案,我给出了两个关于会话状态的主要场景。一个用于确定会话何时在客户端过期,另一个用于确定会话未清除的原因。请阅读答案和附加的链接:)我想你是对的,我错过了阅读。今天我将测试它,而不是清除或删除该键,将该键的值设置为默认值,因为SetInt32是正确名称空间的扩展。如果这样做有效,我需要实施我自己的清晰机制,如果没有更好的方法,它将设定价值观。这个答案帮助我找到了问题所在。非常感谢你。