ASP.NET Role Authentication Breaks With Session - asp.net

Working on an internal portal, we needed certain things about a user stored so we created our own WebUser/WebUserStore but I've hit a weird issue and I was hoping someone would have run into this before.
Being ASP it's a lot of code strewn throughout, so I won't bother pasting it all here. But here is the issue:
Any number of users can login to the home screen.
If any user navigates to a page that makes any session call (either
setting or Session.Remove()) then no more users can log in, the login
page just flashes and you're back at the login screen.
Any user that was logged in while the one user trigger the session will still be able to log out and in and out and in, as long as they still have the ASP.NET_SessionId cookie.
If you delete the ASP.NET_SessionId cookie then that user will get stuck on the login screen as well.
Hacky fixes that may help pinpoint the problem (each of these stops the issue):
Recycling the application pool in IIS resets it so everyone can log in again.**
Setting the following (but you get the nasty url):
<sessionState mode="InProc" cookieless="UseUri" />
Add this right before calling the IdentityHelper.SignIn(...).
Session["ANYKEY!"] = false;
Just adding this empty event to the global.asax.cs
void Session_Start(object sender, EventArgs e)
{
}
This is also on a per-browser basis. So on one machine with 3 different browsers you can replicate the issue using only 1 user. Once you trigger a session call in one browser, the other browsers if they weren't logged in (and had the ASP.NET_SessionId cookie) are now locked out.
Stepping through the login process wasn't revealing anything, everything is normal and fires all the way through authenticationManager.SignIn(...) any seems fine but is mystically not actually authenticated and returned to the login screen?
Can anyone think of what's wrong so that as soon as I touch session all users can't login, and only the ones who already have their session cookie can continue logging in and out?

Related

ASP.net forms auth and timing out

I have a small simple problem, however the following is quite lengthy to explain the issue more.
I have an MVC 4 application using forms authentication. I have it setup using browser session cookies so that they can use the site for as long as they want, but as soon as they close the browser it in essence logs them out.
Now I have added an extra layer of security in the form of an idle timer, so that if they are idle for, say, 5 minutes, an ajax request is sent to the server to delete the forms auth token, return a session expired partial view, and show this session expired view as a modal dialog.
This dialog has a label that shows the users name, and a password input field so they can re-enter their password.
What this means is that if anyone opens up another session they will just go to the login screen as no-one is logged in, and teh same happens if they just refresh teh current screen. But it also means that if the user enters their password on the timeout screen the dialog sends an ajax request to the server to login them in again, and then just removes the dialog.
This all works (mostly) perfectly and they will be on the same screen as they were before, and they will also have everything filled out as they did before for example if they were in the middle of filling out a large form etc.
The issue is, if they have 2 different tabs open in their browser, the first one times out, shows the timeout screen with their name and the password entry box as expected, but the 2nd browser tab when it makes the request for the time-out screen to the mvc method, does not find a logged in user, as no-one is logged in as the person was logged out with the first time-out request. How can I get round this problem? Is there a simple solution? Or is there a better design for how I am doing this?
I've seen this issue in live sites and it's really annoying. It forces users to only have one tab open to avoid getting logged out.
Could you solve it by not logging the user out on the server once the timeout hits, but only delete the session cookie? That way the user will still see the timeout screen on the idle tab, but can still work with the other tab. It can still be an inconvenience, but I think if you really want that timeout screen it might be the way to do it. Unless you want to do it with WebSockets or something similar.

Kill Asp.Net session when the browser or tab is closed

I am using forms authentication with Asp.Net 4. At the moment when the users click on logout link, I clear the session and call FormsAuthentication.SignOut() and this prevents the users from going back to the site without a logging in again.
Now I want to kill the session when the browser or tab is closed. I tried doing this by handling onbeforeunload event, but I ended up killing the session after clicking any internal links.
Any ideas how I can do this?
You can't, but you can come close to.
The authentication cookies are session only, that means that delete by browser when the browser close. Maybe you do not close all browsers tabs, but if you close them all the authentication cookies are lost.
About closing a tab, you do not know if the user have other tab opens.
A possible solution maybe is a call every 10 seconds back to the server to keep this authentication active or not, and set the authentication to end up after 20 seconds. So if not any signal come back, the user have gone. This can be done using javascript. From the other hand this can not let the user logout after some minutes of inactivity, so you may need a combination of this logic with something else.
The best you can do is when your user explicitly logs out to also call Session.Abandon() to remove that user's session. But like others have said there is no way of knowing if the tab/window just closes without doing a logout in this fashion. The session will just hang around on the server until it expires.
I answered another question that had a problem with session being killed when the user edited the web.config on a live site. They were tracking users still being logged in with Session variables (dangerous). But came up with a solution (untested solution) that could help people here.
FormsAuthentication allows you to maintain a person being active and logged in indefinitely. But if they become inactive for e.g. 20 mins they will be logged out which is nice. But to have them logged out at the time the close their browser is not possible (wait for it...) as setting the timeout value to 0 would cause them to be constantly logged in then out again.
So solution : at the time you log a person in using FormsAuthentication you could also set a standard session variable cookie that will be deleted when they close their browser. This cookie would have non-identifying non-account related information. Just a simple "loggedIn:yes".
Now all your code would need to have on it's masterpage/materlayout is a high level call in the page cycle or constructor of the page cycle (or even a custom attribute) that would check both cookie and the user identity:
if(!HasLoginCookie() || !System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
// redirect user to log in page.
}
Basically if the cookie is removed when the browser is closed, you will redirect the user to the log in page.
Hopefully that helps (and works. As I said untested).

Get reason for login prompt when using asp.net membership

I have an asp.net website using the SQL ASP.net membership system. When users are logged in to the website and are inactive for 20 minutes, they get sent to the login page on the next page request. I would like to show some text on the login page that says "you were logged out due to inactivity" when this happens. Is there a built-in way to do this? Or any other ways I could distinguish why the user has been sent to the login page (for inactivity or some other reason)? I have scoured SO and Google but haven't been able to come up with anything.
The reason we need to do this is because we recently migrated from a previous version of the website that was lax about security and didn't have auto logout, so we're getting lots of feedback from users thinking there's something wrong with the website when they are prompted to login again.
Thanks in advance.
It is better to use javascript for this and be proactive about it, showing the timeout remaining if possible otherwise just alerting the user with a messagebox showing that his session has timed out and then redirecting him to the login page. Have a look here for a simple example.
To redirect him to the login page add the following to the below line as in the example:
alert("Your current Session is over."); window.location = "YourLoginPage.aspx";
For purposes of closure, I'll answer my own question. I couldn't find a clean way of doing what I'd like, so I ended up setting a cookie with the login time after the user logs in. Then on the login form page, I see if the login time in the cookie is greater than 30 minutes old (my auth timeout in asp.net) and display a "logged out due to inactivity" message. Otherwise it doesn't display the message.
Not great, but it seems to work. Satisfies the requirement for the vast majority of our users.

Session Time Out

I am developing a web site using ASP.Net 3.5 C#. I am listing all the Online users ( users who re logged in on my site) in my site. I want to track and update user's status in Database when a user has logged out or simply closed the browser or navigated to some other site. In all these cases I want to update user's status as "Logged Out".
How can i move forward with it.
Thanks
Vivek
When the user clicks the button, you can just handle the click event on the server-side (in code-behind) and then log the status change.
For the case where the browser is closed, you can handle the Session_End event in the global.asax, which fires when the session ends:
public void Session_End(object sender, EventArgs e)
{
// Fires when the session ends
}
Legitimate logout (i.e. Logout by clicking on logout button etc.) can be tracked easily. You just have to handle the event and mark their database status logged out.
However closing the browser is one thing I never had a good success with. You will get many solutions over web which would tell you to capture the close button and then ajax request etc, but I did not have success with any one with that.
(Things like Session_End may come handy but there is a Gotcha that thisevent does not get fired, if you are using anything other than IN-PROC session mode so that's not reliable).
You don't really know if the user has closed the browser or not, or if he navigated to another site. I think you need to use some sort of AJAX control that would send some messages to the server in a given time interval to make sure the user is viewing your site.
First check my answer in this other question:
session Handling in asp.net
You wouldn't be able to immediately close a session and track this change if some user closes the browser, shutdowns computer or something like that. This is achieved by playing with session timeout.
Another possibility could be consider an user online if it triggered some operation against the server in some time interval, thing that'll be implemented in your server logic.
Logging out should be easly trackable because it's an "human user" action. Just implement a "UserLogout" event in your authentication manager class or any other class handling authentication and track logouts there.
Client-side user actions like browsing to another page or closing Web browser can't be tracked because technology limitations: API lacks in this area. It's more because of Web paradigm and its principles. You'll need to miss that.

How to get a channelSet to be authorized when a session already exists without calling login

In my Flex application, channelSet is reset on each browser refresh. If you've authenticated and refresh the page and check channelSet.authenticated, it says false, but your remoteObject calls will still work because the server session still exists.
I have a service call that checks for a session on the server and can identify that one exists when a user has already authenticated and not logged out, but how can I bypass login and still set the channelSet.authenticated to true without calling channelSet.login() when they come back to the page(before a timeout occurs, of course)?
UPDATE:
The user session isn't closed if you exit the browser. Currently it does in fact make you log in again. But there is an existing session so blazeds returns a re-authentication error if you're not the user in the session, and it also allows you to login with any password if you are the user because it sees that the session has already been authenticated.
So how can I make it so the session is invalidated upon closing the browser or refreshing? I could do it by automatically logging out when the app starts, but that doesn't seem very elegant.
alternatively I could do something like this:
<body onunload="MyFlexApp.myFlexFunction();">
and call logout automatically when they leave the page.
What's the proper way to handle this?
But they haven't authenticated... how can you be sure that the person using the app now is the same person as before? Closing the browser is supposed to be a good way of breaking a link with an application. If the next person in the internet cafe can get access simply by going to your page, that breaks security somewhat doesn't it?
That's why, even if there's a current session, you should force re-authentication.

Resources