You really cannot stop that and I'm curious why you would. If your system cannot handle having the user in the same tab multiple times then you have a concurrency issue and should resolve it.
Nevertheless let's talk about what you would need to do to implement this kind of functionality. Whether that is doable for you is a different discussion.
- You need to be able to uniquely identify the user across browsers (this covers tabs, windows and browsers). If you require the user to log into your system (or you're using Windows auth) then you can use the user's account.
- You need to detect multiple sessions. A session could be another tab, another window or a different browser altogether. This would also include if the user used a different device altogether. For another tab there are 2 cases: they duplicated the existing tab or they opened in a new tab. In cases where a new tab/window/device was used you can have the client auto-generate some unique identifier. Note that this might not work correctly if the tab is duplicated. Also note that ASP.NET session isn't sufficient here as it is just a value that is passed from client to server and duplicating a tab doesn't change the session.
- Given the user ID and their "session ID" then you'd need to pass that data back to the server and the server would have to respond to whether the "session" should be allowed by determining if the user already has a different session open. Because the user may be interacting with your site and may at any time create a new tab then this would need to be a polling call such that you check periodically. The more frequently you check the more resources you use.
- At some point you need to clean up the session information. The user closing a tab, window, device would need to disconnect the session but since none of that is reliable you'll be in a situation where a user may "close" a session but another session may still be active. This is going to cause false positives.
Honestly this is going to be ugly to solve. An alternative approach is to handle it all on the client side. You could create a local storage object on the client that marks the session in use. Whenever a new tab, window, device is opened then you check for the existence of the local storage object and fail the call if it exists. It has some similar problems though including the fact that it might not get cleaned up properly in all cases. You would have to guarantee that it is removed when the tab closes so maybe session storage on the client would be a good choice. But I don't know how session storage works across windows.
The problem with doing things on the client is it only works for a single browser and device. If you created client storage for Edge and then switched to Chrome it wouldn't have access to the storage as that is browser specific. Even if the browsers share the same storage on a device it is still possible to work around by using multiple devices.
Overall this seems like a problem that shouldn't be solved as it doesn't really accomplish anything. If you really need the feature then you're looking at something server side but that is hard to implement properly. Client side is probably easier but it is limited.