Barry
Barry

Reputation: 2073

How to prevent multiple browser windows from sharing the same session in asp.net

I have ASP.net application that is basically a data entry screen for a physical inspection process. The users want to be able to have multiple browser windows open and enter data from multiple inspections concurrently. At first I was using cookie based sessions, and obviously this blew up.

I switched to using cookie-less sessions, which stores the session in the URL and in testing this seemed to resolve the problem. Each browser window/tab had a different session ID, and data entered in one did not clobber data entered in the other.

However my users are more efficient at breaking things than I expected and it seems that they're still managing to get the same session between browsers sometimes. I think that they're copying/pasting the address from one tab to the other in order to open the application, but I haven't been able to verify this yet (they're at another location so I can't easily ask them).

Other than telling them don't copy and paste, or convince them to only enter one at a time, how can I prevent this situation from occurring?

Upvotes: 15

Views: 55282

Answers (7)

Matthias Meid
Matthias Meid

Reputation: 12521

Think of using ViewState instead of Session, since ViewState renders state information to the client (HTML page). I'm not sure if you'll ever be able to gain detailed control over the browser's session behaviour, because the session ID is maintained by the browser the way the manufacturer did it. So ViewState is more predicable, not only but also for future browser versions.

Upvotes: 5

yazanpro
yazanpro

Reputation: 4772

A solution to that problem can be implemented by the following:

public static class CommonHelper
{
   public static bool SiteGuard
    {
        get
        {
            if(HttpContext.Current.Session["SiteGuard"] == null)
               return true;
            return (bool)HttpContext.Current.Session["SiteGuard"];
        }
        set
        {
            HttpContext.Current.Session["SiteGuard"] = value;
        }
    }
}

public partial class TestPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {
            bool go = false;
            for(int i = 0; i < 50; i++) // wait for the service to work (5 secs max)
            {
                if(CommonHelper.SiteGuard)
                {
                   go = true;
                   break;
                }
                Thread.Sleep(100);
            }
            if(!go)
               Response.Redirect("Login.aspx");

            SiteGuard = false; // from now on, nobody can visit your site
        }
        // Now as long as Page.IsPostBack is true you are in a good shape
    }
}

Add an asmx web service (or any other type of services you think is suitable) to your root project and add the following method to it:

    [WebMethod(EnableSession = true)]
    public void FreeSiteGuard()
    {
        HttpContext.Current.Session["SiteGuard"] = null;
    }

In the master page, or on every page add the following javascript:

<script type="text/javascript">
    window.onbeforeunload = function (e) {
        e = e || window.event;
        if (e) {
            // Invoke web service 
           YourProject.YourWebServiceName.FreeSiteGuard();
        }
    };
</script>

Note that your site response time gets affected by the speed of the web service.

Upvotes: 2

JustAMartin
JustAMartin

Reputation: 13753

This is what I use in ASP.NET MVC to forbid authenticated users to open multiple tabs:

<script language="javascript" type="text/javascript">
    @if(Request.IsAuthenticated)
    {
        <text>
        if (window.name != 'singleWindow') {
            window.location.href = "Content/ErrorPages/SingleTab.htm";
        } 
        </text>
    }
    else
    {
        <text>
        window.name = "singleWindow";
        </text>
    }
</script>

Basically, this sets the window name first time when the user visits the login page. After logging in, for each subsequent page load the window name is tested.

Two problems:

  • does not wok if JavaScript disabled
  • if by mistake the user closes the original tab and then pastes some other link to my website in the address bar, the user will always receive the error page. To give the user a chance to recover, I have included "Log out" link in the SingleTab.htm page, so the user can destroy his session cookie and start a new session.

Upvotes: 2

icelava
icelava

Reputation: 9857

I am unsure why you wish to restrict a session to handle only one inspection process, and then force multiple sessions in order for users to work simultaneously on multiple inspections. That feels like a rather awkward style of isolation.

The web application (and pages) ought to be able to handle multiple inspection processes within a single user session.

Whatever data that is being held in Session variables should not be plainly exposed for singular handling. They ought to be stored in collections that readily identify which set of data belongs to which inspection process. Every page submission back to the web server ought to carry an identifier which inspection process it pertains to, so that the correct session set can be matched and pulled for use.

pseudo code concept

var inspectionID = this.inspectionLabel.Text;
var inspectionSets = (Hashtable)Session["inspections"];
var inspection = (Inspection)inspectionSets[inspectionID];

Upvotes: 3

John Lim
John Lim

Reputation: 31

this is a very good question that i have also thought long and hard about.

Store your main web page in an iframe. Have javascript to check if your web page is still in the parent iframe. If not, then they have opened multiple browser windows.

You need to make sure your entire app is iframe friendly.

Upvotes: 3

Mike Koder
Mike Koder

Reputation: 1928

Create a new sessionId when the request has no referer. That solves the copy-paste url problem. Store the sessionId in the url like you did.

Upvotes: 0

D&#39;Arcy Rittich
D&#39;Arcy Rittich

Reputation: 171559

Must the users be logged in with different accounts to access different physical inspections? It seems to me that as long as the PhysicalInspectionID is part of the URL, then there should be no problem in editing multiple physical inspections at the same time.

E.g.,

http://inspections.mydomain.com/edit/23

Of course, if they copy the URL, they will get a duplicate of the other window, but this will teach them not to do that. Instead, they open another window and browse to the proper inspection (or add a new one) via the UI.

Upvotes: 2

Related Questions