ASP.NET MVC FormsAuthentication.SignOut doesn't work - asp.net-mvc

I'm trying to use forms.signout but sometimes it does not log out the user and he still can navegates through the website.
How can I resolve this? I also configured web.config forms authentication, but it's still not working.
I'm using FormsAuthentication to autenticate an user passing he's login.
Thanks!!

I don't know what the cause is but a few things you might consider/try
are they actually able to still visit pages generated by the server or are they just going back to locally cached versions? What happens when they cause a postback that has code to check if they are authenticated does that work or does it fail? I think the later meaning they are signed out but viewing cached versions of the logged in page in which case you want to instruct the client not to cache the pages using for instances:
Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetNoStore();
You can try manually setting the cookie to be expired but this is a hack
FormsAuthentication.SignOut();
Context.Response.Cookies.Item(FormsAuthentication.FormsCookieName).Expires = Date.Now;
Response.Redirect("~/Somewhere.aspx");

Does the user have the domain (or a parent domain) in their trusted sites or intranet sites? I've run into some issues recently where a user is authenticated, but anonymous under circumstances where this is true. In my case it could also be that a parent site was, at one time, configured to allow windows integrated authentication. I've removed since removed that, but it didn't seem to help the problem. I haven't yet restarted IIS to see if this would have an effect. I've resorted to checking both that the user is authenticated and non-anonymous to ensure that the proper parts of the view are rendered. This is actually more accurate even though my login code should prevent having an anonymous login.

Related

Missing ASP.Net cookies from iOS

I'm experiencing some trouble with an ASP.NET MVC 5 application that has been buggering me for a few days.
The application is using Forms Authentication to control whether a user is Authenticated, and Session to keep track of the user's data.
A few of our users are unable to log in, and I have been able to recreate the problem on a collegue's device. We don't know much about the devices with the problems, except that they all seem to be running iOS. I can't seem to nail down the pattern, though, as one user who reported the problem was running 11.2.5, which I am also running myself without trouble. The collegue's device is running 11.3 beta, but I haven't yet heard of any other users with this version, so I'm unable to pin point that as the problem - which also seems unlikely when one of the users with the problem is running 11.2.5.
The issue happens after the users try logging in. After a successful login, the user is redirected to a specific section of the site, where Authentication is required. Requesting any page in this section redirects you to the login page if you are not Authenticated.
Some of the resources that are requested on this page expect to retrieve some data from Session. For some reason, the Session cookie may sometimes be missing, and other times the Authorization cookie is missing.
For the past few days while I have been hunting this, my collegue's device happened to leave out the Session cookie when requesting our Cachemanifest, in which we expect to be able to generate a specific part based on some data from the Session. This caused the generation to fail, which in turn caused the request to fail.
After changing the generation logic to work around this, with a different solution if the Session cookie is missing, my collegue's device has changed its approach; Now, it includes the Session cookie when requesting this resource, but instead leaves out the Authorization cookie in a subsequent request to a different resource, which is still in the section that requires Authorization. This resource happens to be mentioned in the Cachemanifest, and because this next request does not include the Authorizaiton cookie, that request is redirected to the login page, which is interpreted by the Cachemanifest as an error.
As far as I recall, I haven't changed anything else, so I'm really at a loss as to why this devices' behaviour has changed.
Both of these cookies are included in other requests before and after the failing request, and there doesn't seem to be a pattern between what requests is chooses to leave these two cookies out of, or which cookies to leave out. The only thing that is consistent is that the behaviour doesn't change when retrying after clearing the browser data (only after I made my change, which I still don't see how could result in this behaviour).
The site is forcing HTTPS, so I tried setting the Session cookie to Secure, but that didn't seem to make a difference.
I still need to try setting the Authorization cookie to Secure, but I'm not very optimistic there. I also still need to try reverting my changes to see if the old behaviour reappears.
Has anybody experienced similar problems before, or does anybody have any further suggestions? I know I might be a bit sparse on the details, I'd be happy to provide any further details if I'm able.
Thank you in advance :)

User.IsInRole fails for one action but not for another

I've put a custom authorize attribute into my MVC application, which does
if (!this.Roles.Split(',').Any(filterContext.HttpContext.User.IsInRole))
and if true it will redirect you to unauthorised.
I put this attribute on my controller at controller level.
One action works fine, and in one action I get unauthorised.
Is there some bug or problem in the role system? I've read that logging out and in can force some cache to refresh or something, however the system I am using authenticates with your domain credentials so there is no way to log out.
I've tried restarting the app pool and deleting my session cookie but nothing has worked.
Has anyone experienced this specific issue before or has some guidance on perhaps flushing any caching related to it (assuming it's a caching issue)?
ETA: Another user on the system gave himself the role required for the controller and both actions work fine for him. So perhaps my user is somehow bugged. This is on UAT so slightly more difficult to debug than running on my local machine (which works fine).
ETA2: I'm pretty sure this is a caching issue, as going to the URL with ?1=1 in the query string, it works. I'm unable to invalidate the cache though. This may be a problem in the future when assigning roles to people.
First, we need more code before we could possibly give you any definitive answers. However:
Caching could be a problem. If you're using anything like OutputCache, you should ensure that you're using VaryByCustom and somehow including the user's id or other identifying token in the custom string returned.
If you're adding roles to users, you must either log the user out and sign them back in, or otherwise invalidate their authorization. In Identity, for example, you can simply invalidate the security stamp, which will cause the user to be reauthorized, updating things like claims or roles that have changed since they signed in.

Session not completely abandoned

I'm having an odd problem with my sessions. I haven't found a solution even after searching through the internet for a couple of days and I find it really strange that nobody else seems to be having this problem, which makes me think that it could be something I'm doing wrong.
If I log onto my website and visit a page decorated with the [Authorize] attribute (i.e. it requires the user to have logged on in order to access it), save the request with fiddler, log out and re-issue the request with fiddler one would expect that to fail (or re-direct me to the login page at least) but no, it returns the page as if I were still logged in.
When I'm logging out this is what I do (I'm using asp.net forms authentication)
FormsAuthentication.SignOut();
Session.Clear();
Session.Abandon();
Session.RemoveAll();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId",""));
That should work... but it doesn't.
In case anyone is wondering this is what I am using:
IIS 7.5
MVC 3.0
.NET 4.0
If I log onto my website and visit a page decorated with the [Authorize] attribute (i.e.
it requires the user to have logged on in order to access it), save
the request with fiddler, log out and re-issue the request with
fiddler one would expect that to fail
Why would you expect something like this? Forms authentication uses cookies to track logged in users. When you do FormsAuthentication.SignOut(); all that happens is that you remove the authentication cookie so that on subsequent requests from this browser the cookie is no longer sent and the server thinks that the user is not logged in. If on the other hand you have captured a valid cookie with Fiddler, you are perfectly capable of sending a valid request to the server (in the time for which this cookie is valid obviously). There is nothing on the server for it to know that you used fiddler, right? It's completely stateless.
If you wanted to avoid this behavior (which is by design) you will have to keep track somewhere on the server either a list of online users, or add some flag in the database about the user which indicates whether he is online or not. Then you will write a custom Authorize attribute that will check in this centralized store whether the user is allowed or not to login. When he logs out you will change this flag. Obviously if he closes his browser you won't be able to change the flag but if he signs out normally you will know that even if someone had captured the authentication cookie, he will not be able to use it to issue a valid request.

Authentication loss with IE8 and MVC FileContentResult

ASP.NET MVC2
.NET 3.5
FormsAuthentication
URL: domain.com/myapp
Problem area: Dynamically created PDFs returned as FileContentResult
Everything was working fine until IE8. With IE8, when the user opens a PDF and then returns to the app, he has lost his authentication. I added an expiry on the forms auth cookie and the problem appeared to be resolved. However, I later discovered that the same problem occurs in the parent app. With the persistent cookie, when the user continues in my app (domain.com/myapp), everything is fine, but when he returns to the parent app (domain.com) window he has lost his authentication. The parent app uses a proprietary authentication and authorization architecture that relies on session state.
So my understanding of the problem is that the FileSystemResult does not carry any session information and thus the session is lost. I understand that by adding an expiration to the cookie, the cookie is persisted and that enables the authorization to persist in my app, even when docs were opened.
I don't quite understand why adding an expiry to my cookie transferred the problem to the parent app. So, I was wrong, this has been happening all along in the parent. Interestingly, when I hooked up Fiddler to watch what was going on, the problem went away.
Do you have suggestions to resolve this? I can't think of anything other than something really ugly like writing the file to the server and returning a page with a link to open the file directly.
Based on this question I think I am hosed.
There's some changes to the way IE8 handles persistance cookies which could be the route of your problems. There's an interesting post here that describes a possible solution.
The solution took us quite a while to find online believe it or not,
and when we found it we wanted to kick ourselves for not finding it
sooner. It all stems from the domain attribute of the forms
authentication settings within the web.config file of your
application. We typically left that attribute blank in our apps to
make it easier to develop. Further, none of the other browsers above
cared about that setting and functioned just fine. However, that
changed in IE8 and now that attribute is required.

Logs out and with every refresh though not using TempDataProvider?

I've got an app built using asp.net mvc and deployed over 2 Amazon EC2 instances. I'm using forms authentication to authenticate users. I simply make a quick look up on the given username and password and if I found a match I set an authentication cookie, like so:
if(_repository.Login(username, password))
FormsAuthentication.SetAuthCookie(username, false);
This works fine as long as the application on one machine, but, once I leveraged Amazon Elastic Load Balancing to deploy the site on two machines, the site behaves in a very weird way. When a user logs in, the site recognizes a logged in user, after a refresh or two, the site no longer see the user as a logged in user. If the user keeps refreshing again for some time, the app sees the user as a logged in user again, and this goes forever.
I'm aware that such a problem might occur if I'm storing SessionState inproc. I'm not using SessionState at all.
What am I missing here guys?
Ps: I've edited the session state to be stored on a state server [Though i'm not using neither sessions nor TempData anywhere on my app] and the same weird behavior is there.
You need to synchronize your <machinekey> between all servers in your farm. Otherwise the forms authentication ticket is only good for the machine which issued it. I doubt this has anything to do with Session/TempData.

Resources