2

我使用 ASP.NET 成员 API。这会自动注销非活动会话。我不希望这种自动注销。我使用了一些变通方法,例如在指定时间后在 ajax 中调用页面。或者我使用 iframe 方法来保持会话处于活动状态。但这不太适合我的需求。我想完全禁用此注销功能。

注意 我的问题是对这篇文章的回应这个

增加会话超时并不总是有效

乍一看,增加 C# ASP .NET 的 web.config 文件中的会话超时值应该可以解决问题。您可以假设通过将下一行中的超时值更改为 60 分钟,用户将在整个 60 分钟内保持登录到 Web 应用程序会话。

<authentication mode="Forms">
  <forms name="MyAuth" timeout="60" protection="All" loginUrl="~/Web/Login.aspx" slidingExpiration="true" />
</authentication>

<sessionState mode="InProc" cookieless="false" timeout="60" />

然而,这实际上存在两个问题。第一个问题是,将超时值设置为大于 1 小时将导致服务器上保留过多的内存,因为 IIS 在会话期间保留了所有会话内存。想象一个高流量站点的超时值为 5 小时,它保存了数千个用户会话的所有会话数据。第二个问题可能出现在测试应用程序时,Web 应用程序通常会在 15 分钟后超时。到底发生了什么?虽然问题实际上可能是在 IIS 中为会话超时或连接超时属性配置的值(在共享主机的情况下,您甚至可能无法访问),但显然我们需要将会话超时控制到我们自己的双手。

4

3 回答 3

2

将身份验证 cookie 设置为不结束是太冒险了。

为什么,因为任何人在任何时候都可以使用任何生成的经过身份验证的 cookie 再次登录。

要了解更多相关信息,您可以阅读该文章:FormsAuthentication.SignOut 方法不能防止 ASP.NET 应用程序中的 cookie 回复攻击”

并查看一些相关问题, Form Authentication - Cookie replay attack - protectionFormsAuthenticationTicket cannot be invalidated server side。导致cookie回复攻击

一种解决方案是使用处理程序和简单的 javascript 调用它并不时更新登录会话。

html/javascript 部分:

<img id="LiveImg" width="1" height="1" alt="" src="keepsessionalive.ashx?" /> 
<script>
var myImg = document.getElementById("LiveImg");
if (myImg){
    window.setInterval(function(){
          myImg.src = myImg.src.replace(/\?.*$/, '?' + Math.random());
        }, 3000);
}
</script>

并且keepsessionalive.ashx可以包含:

// 1x1 transparent GIF
private readonly byte[] GifData = {
    0x47, 0x49, 0x46, 0x38, 0x39, 0x61,
    0x01, 0x00, 0x01, 0x00, 0x80, 0xff,
    0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x00, 0x01, 0x00, 0x00, 0x02,
    0x02, 0x44, 0x01, 0x00, 0x3b
};

public void ProcessRequest (HttpContext context) 
{
    // send the emtpy image
    context.Response.ContentType = "image/gif";
    context.Response.Buffer = false;
    context.Response.OutputStream.Write(GifData, 0, GifData.Length);
}

如果您还想保持会话活动,请与身份验证一起使用IRequireSessionState您的处理程序。

在每次调用时,身份验证凭据都会更新,并且您的会话将保持 - 如果用户出于任何原因离开,cookie 将过期,您可以避免可能的重放攻击。

我还在这个类似的答案中介绍了自动图像重新加载的技巧:
保持相关的 ASP.NET 应用程序的会话从另一个 ASP.NET 应用程序中保持活动
状态重置会话超时而不在 ASP.Net 中进行回
发什么是处理会话超时的最佳方法asp.net
在定义的时间间隔后自动刷新 ASP.NET 网页?

于 2013-05-27T20:18:53.230 回答
1

同样的事情发生在我们身上,原因是我们的服务器必须处理 IIS 中的超时(即 IIS 请求超时),我们没有任何特定的控制(在我的网站所在的服务器上)。

所以我们这样做了。(不是非常理想,但它对我有用。我希望你有一个母版页来完成所有这些工作。否则你必须在每个页面上都这样做)

假设您想将超时增加到任意限制,例如 1 天

1.首先将web.config中的那个增加到默认值。20分钟。最大值为一年。

2.在母版页底部运行一个空的 iframe。

<iframe id="SessionHandler" src="/html/SessionHandlerHack.aspx" frameborder="no" height="0" width="0"></iframe>

3.在页面的代码隐藏处,写

C#

protected void Page_Load(object sender, EventArgs e)
{
    //Session timeout is now at 20 minutes. due to the unreliable nature of session,
    //we are setting the meta-refresh to be 15 minutes to be on safer side.
    Response.AddHeader("Refresh", "900");
}

VB.NET

Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    'Session timeout is now at 20 minutes. due to the unreliable nature of session,
    'we are setting the meta-refresh to be 15 minutes to be on safer side.
    Response.AddHeader("Refresh", "900")
End Sub

是的,它相当于添加了一个刷新标头,我们在代码隐藏中使用变量来操作 15 分钟的值。是的,

<meta http-equiv="refresh" content="900">

在 ASPX 页面本身上就可以了。

4.在母版页上运行一个 JavaScript 计时器,该计时器在 24 * 60 * 60 * 毫秒(即 1 天)到期。到期时将用户重定向到这样的注销页面。

var timeOut = 86400000; //24 x 60 x 60 x 1000 ie, number of milli-seconds in a day
$(document).ready(function () {//window.onload for you maybe?
    window.setTimeout(function () {
        window.location = "/LogIN.aspx?action=logout";
    }, timeOut);
});

逻辑是站点不会超时,因为超时具有滑动到期,并且页面中的 iframe 将每 15 分钟刷新一次,从而重新设置会话到期。现在,JavaScript 计时器也在页面上运行,并且不知道页面中 iframe 发生的刷新,并充当我们所需超时的超时裁判。此外,当页面重新加载/导航离开并重新启动计时器时,它将被刷新。

第一次听有点多。但这对我们有用,这是迄今为止我们找到的唯一解决方案(并不是我们每天都在研究它:P)

希望这可以帮助。快乐的会议黑客!

于 2013-05-27T20:04:02.390 回答
0

将此添加到您的 web.config:

<system.web>
<authentication mode="Forms">
      <forms timeout="99999999"/>
</authentication> 
</system.web>
于 2013-05-27T18:06:33.463 回答