MVC: logged in, but no session vars? - asp.net-mvc

I use chrome as debugging browser.
When I start my MVC (Razor) website, click the stop button and the website keeps running in chrome ,while I can make changes in VS ... perfect.
But sometimes (due to I don't know what changes), when I refresh a page, I'm still logged in, but I looses all my session vars.
How can I catch if session vars is cleared, so I can take my users back to login page? (I need a kinde global.asax page_request method.
I do have the .. <forms loginUrl="~/Account/LogOn" timeout="2880" /> ... but Im not logged out - only session vars are cleared.

It's because your login state is persisted in a client cookie. The session state is persisted on the server in memory (or whatever). When your app restarts the session is cleared but the user still has a valid forms authentication token (assuming forms authentication here) on their machine. Forms authentication does't use session in any way by default.
So, at the beginning of the request, you can either reload the user session from the database when it's null (I think this is the preferred approach if possible) or redirect the user to the login screen with a message saying "ooops, sorry we've lost your session" (which is not good!)

If you use the built-in Authorization functionality, you can just add the [Authorize] attribute. There's some info on using custom authentication here:
ASP.NET MVC Authorization

Lee Gunn explained it well. One solution would be to create a custom filter attribute similar to Authorize that verifies the session has the values you're expecting and decorate the appropriate controllers/actions.

Related

Log a user off when ASP.NET MVC Session expires

In ASP.NET MVC in one of the WCF services I place an object into the HttpContext.Current.Session object.
When the session times out and the session is cleared of all objects I want to log the user off but have been unable to find a way.
In Global.asax
when the Session_end method is called the Response object and HttpContext.Current are both null.
Any ideas how to log the user off is appreciated.
When the session times out the user no longer exists in any case. If what you are trying to do is clean up open browser windows you would need to implement a timer based on time remaining before session expiration.
SignIn and signout have to do with adding or deleting cookies or tokens to authenticate with an external service. The call that you see should be in the login controller and should not be moved to the global.asax.
No additional action is required.
I think it is wrong practice to try to keep session and authentication cookie in sync. Session and cookie are different things. You can login with multiple users during the same session period. You start a new session when you open some url and it ends when you close the window or it expires on the server side. For more information about session - authentication cookie relationship please read the following answer: asp.net cookies, authentication and session timeouts
Anyway if you want to do it you can use one small trick. You have to periodically call your server with ajax call for example call YourWebsite.com/chcecksession page each n seconds. There you have to check for the existence of a session variable. If it does not exists anymore then simply call FormsAuthentication.SignOut(), refresh your page and the user will be logged out.
I'm not sure about your implantation of WCF as I'm not that versed in WCF. I'm currently building a large scholarship application and we want to restrict logins to a single login per user. I have a table setup to track the userID and a GUID that I store in their Auth Cookie. You could use a session ID instead. I'll be caching the table and refreshing the cache each time I add or remove an entry. I'm using SignalR (you can get as a NuGet package) to maintain connections with each of our clients. When they close their browser SignalR can immediately report that the user is gone and I can terminate their record from the session tracking table. In your case, you could kill the session. Additionally if a user tries to login again, I can see they are already logged in. I then kill their original session and allow them to log in new.
It took a few hours to get used to using SignalR and I highly recommend the videos on Plural Sight.
Set both timeouts in following configuration to exact number of minutes. Make sure you set slidingExpiration to true, that is same as authentication will continue to extend to 30 minutes after each request, as session continues to extend after each request.
<authentication mode="Forms">
<forms loginUrl="~/Auth/SignOn.aspx" timeout="30" slidingExpiration="true" />
</authentication>
<sessionState timeout="30" />

session expired error in asp.net MVC 3

I am working on asp.net MVC 3 application. I am facing an issue related to session expiration. When I am logged in and website is inactive for 10-15 minutes, I try to click any link, It says object reference null error. I want that when session is expired, on clicking any link, either I should be redirected to login page with error message that session expired, or popup with same message. how to implement it in asp.net MVC 3.
Regards,
Asif Hameed
I am guessing that your code grabs something from session state and then uses it without checking if it is null first.
I would suggest looking at that code, and adding the null check. if null, then redirect to the login page as you need.
There are two timeouts normally seen in a .net web app.
The first is the session timeout. It is set in the sessionState tag.
<sessionState timeout="number of minutes" ...></sessionState>
The second is the forms cookie timeout. It is set in the authentication tag.
<authentication mode="Forms">
<forms timeout="number of minutes"/>
</authentication>
It looks like your session is timing out before your forms cookie times out.
It is better to have your session last a few minutes longer than the forms authentication cookie, that way the user can log back in within a few minutes and still have their session. I've had problems, such as the one you described, with setting them to the same value.

Session issue when cookies are disabled in asp.net mvc

Whenever cookies are disabled in my browser and then i try to login on login page it unable to create session and so unable to login in system. Then i change the cookie setting to
<sessionState cookieless="true" timeout="20" />
in my web.config and then try to login Post action of the login function it doesnt call and whenever i input username and password and sumbit it, it call simple login action instead of Post one. What is the issue?
You shouldn't confuse session with authentication. If you are using Forms Authentication a separate cookie will be used to track authenticated users. Here's a good article explaining how to enable cookieless forms authentication. You could set the cookieless attribute on the <forms> element.
Quote:
"im not using form authentication instead i have built my own login mechanism. I just want to login user whenever cookies are disabled in user browser"
End Quote
That's the problem with rolling your own login: you lose all the benefits of using Membership Providers. You should cast your "own login mechanism" into a custom membership provider so that you can benefit from what ASP.NET provides out of the box.
Writing a custom membership provider is not difficult, and there are loads of articles, samples and blogs on the subject.
4guysfromrolla.com, for example, has a series of articles dedicated to the ASP.NET membership provider.

When does the .NET FormAuthentication ticket get checked and how do I tap into this event?

We are attempting to integrate an ASP.NET MVC site with our client's SSO system using PingFederate. I would like to use the built in FormsAuthentication framework to do this. The way I've gone about it so far is:
Set up my Web.config so that my FormsAuthentication LoginURL goes to my site's "BeginAuthentication" action on a "Security" controller. From this action, I set up some session variables (what URL was being accessed, for example, since Ping won't send this info back to me), and then redirect to our client's login page on an external site (www.client.com/Login for example).
From here, the authentication takes place and a cookie is generated on the same domain as the one that our application is running on which contains the unique identifier of the authenticated user, I've set it up so that once this happens, the Ping server will redirect to my "EndAuthentication" action on my "Security" controller.
In this action, I call my membership class's "ValidateUser" method which takes this unique identifier from the cookie and loads in the user on our application that this ID refers to. I save that logged in user in our Session (Session["LoggedInAs"], for example) and expire the cookie that contains the id of the authenticated user that the SSO system provided for me.
All of this works well. The issue I'm wondering about is what happens after our user has already authenticated and manually goes back to our client's login page (www.client.com/login) and logs in as another user. If they do that, then the flow from #2 above to number 3 happens as normal - but since there already exists an authenticated user on our site, it seems as though the FormsAuthentication system doesn't bother kicking off anything so I don't get a chance to check for the cookie I'm looking for to login as this new user. What I'd like to do is, somewhere in my Global.asax file (probably FormsAuthenticate_OnAuthenticate), check to see if the cookie that the SSO system sends to me exists, and if so, sign out of the application using FormsAuthentication.SignOut().
Another issue that seems to be related is that if I let my Session expire, the FormsAuthentication still seems to think I am authenticated and it lets me access a page even though no currently logged in user exists in my Session, so the page doesn't render correctly. Should I tap into the Session_End event and do FormsAuthentication.SignOut() here as well?
Basically, I want to know when the authentication ticket created by
System.Web.Security.FormsAuthentication.SetAuthCookie(..) gets checked in the flow of a request so that I can determine whether I need to SignOut() and force revalidation or not.
Thanks for any help. Sorry for the length of this message, trying to be as detailed as possible.
Mustafa
Welcome to the small section of Hades that is mixing session with formsauth.
If your needs are as complex as presented, you would get more sleep if you implement a full provider stack to share amongst the participating sites. Easier said than done, I know.
But to address your question:
from http://www.codeproject.com/Articles/39026/Exploring-Web-config-system-web-httpModules.aspx
On the way in....Check ticket and set identity #
app.AuthenticateRequest += System.Web.Security.FormsAuthenticationModule.OnEnter-->OnAuthenticate
On the way out... set the ticket and redirect as necessary
app.EndRequest += System.Web.Security.FormsAuthenticationModule.OnLeave
Reflector is your friend. ;-)
I don't know about a specific event for when the cookie is checked, but you could place the appropriate logic in Application_BeginRequest() and check the user's authentication state there.
Another issue that seems to be related
is that if I let my Session expire,
the FormsAuthentication still seems to
think I am authenticated and it lets
me access a page even though no
currently logged in user exists in my
Session, so the page doesn't render
correctly.
The life of the cookie (how long until ASP.NET feels it needs to ask for a password again) and how you are managing state are unrelated. The ASP.NET authentication is cookie based so that, should a developer want to, he could turn off viewstate, session, use no query strings or hidden fields and authentication still works.
If you want to tie the interval at which you request the password to how you are persisting data, then you will want your session expiration to be roughly the same as the cookie expiration, but they will never quite match up. It would be better to have two policies (one for how fast you throw away a users session data and one for how long you are willing to wait before you need to reask for a password)

Set authentication as true for the view of the control that performs the authentication in ASP.Net MVC

In the authentication control I have the following line to mark a user as authenticated in the system (after checking out the password):
FormsAuth.SignIn(userName, rememberMe);
and if I redirect, which is the standard behvaior, everything is ok. But if I show a view right away, the usual ways to check whether a user is authenticated:
Page.User.Identity.IsAuthenticated
Request.IsAuthenticated
don't work. They say the user is not authenticate. How can I make the authentication effective immediately or is there another way to check that would allow me to find out when the user just logged in?
FormsAuth.SignIn is a function which is generated when you create a new ASP.NET MVC project from Visual Studio.
That function simply calls FormsAuthentication.SetAuthCookie, which according to the docs, sets the authentication cookie in the response.
This explains why it works if you redirect (because the client will play back the cookie in the subsequent request), but not right after the call.
Redirecting is the right/conventional way to do this, but if you absolutely insist on checking authentication before a redirect, then you could create an IsAuthenticated flag in session state and refer to that when checking.
On your Controllers, you should be able to use the following to check if they're authenticated.
User.Identity.IsAuthenticated;
I would check to make sure that your AccountController is properly saving the Principal object as you move from page to page.
In addition to using the FormsAuth.Signin or FormsAuthentication.SetAuthCookie, you can also set the User.Identity manually in your sign-in control when the sign-in code executes. As written above, the reason is because the FOrmsAuth.SignIn simply sets the authentication cookie to be picked up next time in the Request_OnAuthenticate event. (Which simply decodes the cookie and sets the HttpContext.User property)

Resources