【问题标题】:Automatically sign out from Forms Authentication in ASP.NET when browser is closed关闭浏览器时自动从 ASP.NET 中的表单身份验证注销
【发布时间】:2013-08-12 15:18:17
【问题描述】:

当浏览器关闭或用户输入新地址时,有没有办法强制 ASP.NET 退出其身份验证?

如果浏览器保持打开状态,那么我需要保持用户的身份验证,因此身份验证票证上的长时间超时是可取的。

【问题讨论】:

  • 另一种想法:在每个页面上生成一个随机 id,并将这个 id 放入每个链接的查询字符串中。在下一页单击时,如果查询字符串中的 id 与最后生成的 id 不匹配,则用户在流程之外做了一些事情。
  • @the_lotus 如果用户点击后退按钮(有效操作)怎么办?
  • 如果返回按钮是一个有效的动作,那么这将不起作用。

标签: c# jquery asp.net asp.net-membership forms-authentication


【解决方案1】:

不确定这是否仍然是一个问题,但这解决了我的问题。只需将以下内容添加到起始页的 Page_Load 事件中:

protected void Page_Load(object sender, EventArgs e)
{
    if (Request.UrlReferrer == null || string.IsNullOrEmpty(Request.UrlReferrer.AbsolutePath))
    {
        Session.Abandon();
        FormsAuthentication.SignOut();
        FormsAuthentication.RedirectToLoginPage();
    }
}

【讨论】:

  • 喜欢它,所以反过来看 - 如果它们是新鲜的,请退出。如何打开新标签页?
  • 终于有时间玩这个了 - 遗憾的是它不能使用后退按钮,所以如果用户只是输入一个新地址,做一些浏览然后不要关闭浏览器,其他人可以进入并点击后退按钮,直到他们来到安全站点,然后就好像他们是用户一样访问。我找不到任何方法来检测是否按下了后退按钮。
【解决方案2】:

我一直在研究这个问题,阅读并看到各种帖子和答案,猜想和猜测。

这个解决方案确实有一个重要的警告 - 弹出窗口(“烧他!!!”我听到你哭了)是必需的,JavaScript 也是如此。但是,鉴于您需要如此安全地实现此功能,我猜测用户会接受此功能以维护安全性,并且您可以为启用 JavaScript 编写代码。

第 1 步 - 验证弹出窗口是否已启用 - 如果未启用,请重定向到有关如何启用的说明

在 Global.asax

设置会话变量以验证是否已检查弹出窗口:

void Session_Start(object sender, EventArgs e)
{
    // Code that runs when a new session is started
    Session["popupsChecked"] = false;
}

在 Page.aspx / masterPage.master

检查会话变量,如果为假(本次会话首次访问该站点),则注入 JavaScript 以检查弹出窗口的可用性:

if (!IsPostBack)
{
    if (!(bool)Session["popupsChecked"])
    {
        Page.Header.Controls.Add(new LiteralControl("<script src=\"/js/popupCheck.js\" type=\"text/javascript\"></script>"));
    }
}

popupCheck.js 文件(文件"enablePopups.aspx" 是有关如何为相关站点启用弹出窗口的说明)

$(function () {
    result = window.open("/static/popupCheck.aspx", "popped", "width=10, height=10, location=no, menubar=no, status=no, toolbar=no, scrollbars=no, resizable=no");
    if (result != null) {
        // Not blocking
        if (window.location.pathname != "/static/enablePopups.aspx") {
            window.location = "/";
        };
    }
    else {
        //blocking
        if (window.location.pathname != "/static/enablePopups.aspx") {
            window.location = "/static/enablePopups.aspx";
        };
    }
});

最后,popupCheck.aspx

<head runat="server">
    <title>Popup Checker</title>
    <script language="javascript" type="text/javascript">
        window.close();
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        Popup windows are enabled, please close this window.
    </div>
    </form>
</body>
</html>

在代码隐藏中包含以下内容 - 这将停止任何进一步检查以查看是否启用了弹出窗口:

protected void Page_Load(object sender, EventArgs e)
{
    Session["popupsChecked"] = true;
}

因此,此时我们已经“强制”用户为此网站启用弹出窗口 - 如前所述,在我看来,网站内容应该证明这种烦恼是合理的

第 2 步 - 检查他们要去哪里,如果他们不在,弹出注销

在您的主要 javascript 块、文件、数据中,或者您现在正在这样做

var siteLinkClicked = false;
var isAuthenticated = false;
$(function() {

   // Check if user is authenticated
   if ($("#someElementThatOnlyAppearsWhenLoggedIn").length) { isAuthenticated = true; };

   // Check if any of the links clicked are in the site 
    $("a, input").click(function () { // -- You may need more then "a" and "input" tags, or exceptions
        siteLinkClicked = true;
    });

    $(window).bind("beforeunload", function (event) {
        if (siteLinkClicked == false && isAuthenticated == true) {
        // popup the logout page
        window.open("/popupLogout.aspx", "popupLogout", "status=0,location=0,directories=0,menubar=0,scrollbar=0,resizable=0,width=400,height=200")
        };
    });
});

还有 popupLogout.aspx

我们有一些 javascript 来检查父(打开器)位置,如果它与此弹出窗口相同(即用户单击了刷新 - 或者您错过了 siteLinkClicked 的元素)然后关闭窗口而不做任何事:

$(function () {
    setTimeout(checkParent, 5000); // Give some time for the new window to load if they've navigated away - A counter could be added, logging off in 5... 4... 3... You get the idea.
    window.blur(); // And stick this to the back
});

function checkParent() {
    var openerLocation = null;
    try {
        openerLocation = window.opener.location.hostname
    } catch (e) {
        openerLocation = null;
    }

    if (openerLocation == window.location.hostname) {
        window.close();
    } else {
        $("#<%= cmdLogout.ClientID %>").click();
        // setTimeout(window.close(), 1000); // Removed and add a redirect to static "loggedOut.html page
    };        
};

如果位置不同/未定义,则单击按钮,然后关闭窗口:

&lt;asp:Button Text="logout..." runat="server" ID="cmdLogout" OnClick="cmdLogout_click" /&gt;

然后按钮触发如下代码:

protected void cmdLogout_click(object sender, EventArgs e)
{
    System.Web.Security.FormsAuthentication.SignOut();
    Session.Abandon();

    Response.Redirect("~/static/loggedOut.htm"); // Added, can self close if needed in the HTML
}

最终限制重申

如果没有 JavaScript 或弹出窗口,此方法将无法工作,至少对我而言,我将在安全至上的受控环境中工作,因此此解决方案值得最终用户烦恼。

如果你必须走到这些极端,那么我只能假设数据和应用程序足够敏感,以迫使用户必须启用 javascript 并且必须启用弹出窗口。

【讨论】:

    【解决方案3】:

    您似乎可以设置一个较长的过期时间,也可以将其设置为不持久,以获得您似乎正在寻找的确切行为。例如:

    FormsAuthentication.SetAuthCookie("username", true); 
    

    这会将其设置为持久存在,以便当您关闭浏览器时,它会保留 cookie,这样即使他们关闭浏览器并再次加载您的网站,它也会使他们不必登录太久因为还没有到期。

    另一方面:

    FormsAuthentication.SetAuthCookie("username", false); 
    

    这会将 cookie 设置为不保留。当您关闭浏览器时,cookie 将被删除,从而在您下次加载它时强制登录,无论到期时间是否发生。有关更多信息,请参阅FormsAuthentication.SetAuthCookie

    【讨论】:

    • 我喜欢@frankrun 的想法!这如何与他们在同一页面上离开网站然后返回?我会做一些实验看看。
    猜你喜欢
    • 2016-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 2012-12-23
    • 2012-04-07
    • 1970-01-01
    相关资源
    最近更新 更多