0

Is there a way to force ASP.NET to sign out from it's authentication when the browser is closed or the user types in a new address?

If the browser is left open then I need to keep the user authenticated, so a long timeout on the authentication ticket is preferable.

3
  • An other idea: generate a random id on each page and put this id the querystrings of each link. On the next page click, if the id in the querystring doesn't match the last generated id then the user did something outside the flow. Commented Aug 12, 2013 at 17:10
  • @the_lotus What if the user clicks the back button (a valid action)? Commented Aug 12, 2013 at 17:31
  • if the back button is a valid action, then this won't work. Commented Aug 12, 2013 at 17:35

3 Answers 3

4

Not sure if this is still an issue but this resolved the issue for me. Just add the following to the Page_Load event of your Start Page:

protected void Page_Load(object sender, EventArgs e)
{
    if (Request.UrlReferrer == null || string.IsNullOrEmpty(Request.UrlReferrer.AbsolutePath))
    {
        Session.Abandon();
        FormsAuthentication.SignOut();
        FormsAuthentication.RedirectToLoginPage();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Like it, so look at it the other way round - should they arrive fresh, sign them out. How does it work with opening new tabs?
Finally had to time to play around with this - sadly it doesn't work with the back button, so if a user were to just type in a new address, do some browsing then not close the browser, someone else could come on and hit the back button until they came to the secure site, then access as though they're user one. I can't find any way to detect if the back button has been pressed.
1

I've been working on this for some time, reading around and seeing various posts and answers, conjecture and speculation.

This solution does have a significant caveat - Popup windows ("BURN HIM!!!" I hear you cry) are required, as is JavaScript. However, given that you have a need to implement this so securely, I'd hazard a guess that the users would accept this to maintain security, and you could code for JavaScript being enabled.

STEP 1 - Verify that popups are enabled - If not, redirect to instructions on how to enable

in the Global.asax

Setup a session variable to verify if popups have been checked:

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

in Page.aspx / masterPage.master

Check the session variable, if false (first visit to the site this session), inject the JavaScript to check for popup availability:

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

The popupCheck.js file (The file "enablePopups.aspx" is instructions on how to enable popups for the site in question)

$(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";
        };
    }
});

And finally, the 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>

With the following in the codebehind - This will stop any further checks to see if popup windows are enabled:

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

So at this point we now have "forced" the user to enable popups for this site - As said, the site content should justify this annoyance in my opinion

STEP 2 - Check for where they're going, if they're off, popup the logoff

In your main javascript block, file, data, or however you're doing it now days

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")
        };
    });
});

And the popupLogout.aspx

We have some javascript to check for the parent (opener) location, if it's the same as this popup (i.e. the user has clicked refresh - Or you've missed an element for siteLinkClicked) then just close the window without doing anything:

$(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
    };        
};

If the location is different / undefined then fire off a button click, then close the window:

<asp:Button Text="logout..." runat="server" ID="cmdLogout" OnClick="cmdLogout_click" />

And the button then triggers the following code:

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
}

Final limitation reiteration

Without JavaScript or popups this method will not work, and for me at least, I'll be working in a controlled environment where security is paramount so this solution is worth the annoyance of the end users.

If you have to go to these extreme ends, then I can only assume that the data and application are sensitive enough to force the users to have to enable javascript and have to enable popups.

Comments

1

It seems like you could set a long expiration time and also set it not to persist to get the exact behavior you seem to be looking for. For example:

FormsAuthentication.SetAuthCookie("username", true); 

This sets it to persist so that when you close your browser, it will preserve the cookie so that even if they close their browser and load your site again, it will make it so that they don't have to login so long as the expiration time hasn't occurred.

On the other hand:

FormsAuthentication.SetAuthCookie("username", false); 

This sets the cookie to not persist. When you close your browser, the cookie is deleted thereby forcing a login the next time you load it whether the expiration time happened or not. For more info here, see FormsAuthentication.SetAuthCookie

1 Comment

I like the thinking @frankrun! How does that work with them navigating away from the site on the same page and then returning? I'll run some experiments to see.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.