Authentication loss with IE8 and MVC FileContentResult - asp.net-mvc

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.

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 :)

Umbraco 7 custom cookies

I am running an MVC site along side Umbraco. The MVC site handles its own authentication completely separate to Umbraco, and ASP.NET Forms authentication for that matter. It sets a cookie and uses that internally to keep track of things.
Everything works fine for the most part, but if I am logged into my MVC site with the aforementioned cookie set, I try to login to the Umbraco admin section using the correct Umbraco credentials, it authenticates me and redirects me to the admin section but the WebAPI calls start to fail. The first is a call to: /umbraco/backoffice/UmbracoApi/UpdateCheck/GetCheck which returns a 417 Missing token null HTTP error response.
If I delete my custom cookie and refresh the page everything works fine.
I don't understand how my cookie can interfere with Umbraco's. It's not using ASP.NET Forms authentication or anything.
This error occurs because your request is not sending up the required angular CSRF headers + cookie. I'm not sure why this would be the case but it does seems strange if it is a fault of your custom cookie. Perhaps you can tell us some more information about your issue: Cookie name/value, steps to reproduce, specific version of Umbraco, hosting environment, etc....
Some info as to what is going on, the code that returns this error is here:
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/WebApi/Filters/AngularAntiForgeryHelper.cs#L94
This is where the CSRF cookies are set:
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/WebApi/Filters/SetAngularAntiForgeryTokensAttribute.cs
and this attribute is applied to two actions, one for login and one when we retrieve the current user data:
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/Editors/AuthenticationController.cs#L103
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/Editors/AuthenticationController.cs#L84
This is where the header is set in the JS:
https://github.com/umbraco/Umbraco-CMS/blob/5b9a98ad6ae9e63322c26f7b162204e34f7fcb54/src/Umbraco.Web.UI.Client/src/init.js#L11
Depending on your hosting environment/setup there has been strange reports of some firewalls stripping/changing data, for example:
http://our.umbraco.org/forum/umbraco-7/using-umbraco-7/47340-Umbraco-7-plus-ISA-Server-2006
Hopefully given the info above you might be able to pinpoint where the problem starts.
My initial thought is that you by accident used a key value for your cookie that is reserved by Umbraco, which could result in the wrong cookie being read, causing issues. The solution to this would be to simply rename your cookie.
If this is not the case I have another theory:
HTTP requests will always include all cookies which path/domain matches the domain of the resource you are requesting. They are sorted by path length primarily, and secondarily by creation time. If Umbraco backend for some reason finds the cookie used for authentication by its index number (wouldn't even be surprised) in the list, rather than key value, your custom cookie would cause the index to shift, thus making Umbraco look at the wrong cookie
So, if renaming the cookie didn't do anything, a fun thing to try could be to set path of the cookie to the shortest possible path, which would make your browser put the cookie further down the list, so the index won't shift.
It's just a theory though, so I'm interested in hearing how it goes :)

domain forwarding/masking with ASP MVC anti-forgery token error

My MVC site uses the antiforgeryToken code, which works well in chrome, firefox. However, in IE10, I have noticed that it gives me the error:
required anti-forgery cookie "__RequestVerificationToken" is not present
Definitely a cookie related issue as when I allow all cookies, it works fine. (ie. lowest privacy settings)
However, I have also noticed that when I go to GoDaddy and take off domain forwarding masking, (but leave the domain forwarding in) it also works fine.
Is there a way to get this working with the masking? (Masking is an option which allows forwarding of a domain while hiding the non-domain name. I am doing this because I am using Azure websites and would rather have my users see my actual domain name, not xxx.azurewebsites.net)
Thanks for any help here!
Domain forwarding masking works by hosting your real URL inside a frame. In that scenario, your real website content is coming from a different domain than the main page's domain. As such, any cookies your site tries to set will be interpreted as 'third party cookies' and are going to be blocked by any browser set to block those kinds of cookies (including, apparently, IE10 with its default settings).
Frankly, I think you are fighting a losing battle here. These kinds of cookies are benign in your use case, but they look exactly like the kinds of cookies advertisers are using to track people across websites, and so I would expect browsers to be even more hostile to them as time goes by.
I think your options in this case are to not need cookies (e.g. don't use the anti CSRF features provided by ASP.NET MVC), or to move your website to a host that allows you to directly serve your content at the real URL (so that you don't have to use the godaddy masking technique). The latter is probably the best long term solution.

Cookies being preserved despite app telling them to expire

While the problem happens almost always to users in Internet Explorer, it has happened in Firefox and Chrome a few times as well.
The issue is in which users attempt to login and either get a 422 error or are simply re-directed back to the login screen. We have a wildcard cookie, but we recently switched it to targeting www (about 3 months ago) and the previous cookie was set to expire at the end of the session.
We also recently switched to Devise authentication from Restful_athentication in hopes that it would fix the issue, but it doesn't seem to be helping. However, I don't see how these are related as they don't really manage the cookies, Rails does, they just put things in the cookies. I thought maybe the issue was that restful-auth was putting something in that got corrupt under weird conditions, but that apparently was not the case at all
UPDATE
After we switched to Devise, users encountering this problem no longer got a 422 error, but now the page just refreshes and nothing happens. I should also mention that when they enter in their email to retrieve their password (as they think they're entering their password in wrong), it returns that the email is not found in the system.
When they clear their cookies, particularly in IE, they still run into the same problem. I've walked a few users through searching for the individual cookies in Firefox and that has solved the problem. However, simply just going to clear cookies the normal way didn't work. The issue was mainly effecting IE7 users, but seems to be all across the map, with users reporting the issue on Chrome, IE8, Firefox, Safari and Safari for the Ipad.
Also, here's a link to the code for the session_store.rb here and here the host is set in def ensure_domain, which is here
UPDATE 2
I just made a very minor adjustment and it changed it so it always sends a host. I tried logging in every different way on every browser and didn't run into any issues. I'm hoping this helps
UPDATE 3 (LAST UPDATE)
We tried a combination of a few different things, so while I'm not exactly sure what fixed it, my best guess is removing the cache from 4 days to when the session ends/browser closes. While I'm not thrilled about this as I personally dislike having to login every time, I'd rather have the problem fixed (and this issue didn't start occurring until after we changed the cache length to 4 days.)
Sending a host was a mistake and actually made the problem worse for everyone as no one was able to login. Another strange thing was that when looking at the cookies created there were two Session ID cookies, which I would guess were causing the conflict, particularly with IE7. Some users are having to clear their cookies to get logged in still, but at least that seems to be working most of the time.
To any having a similar issue, sorry I couldn't be of more help!
If an HTTPS cookie is set to "secure", it WILL NOT be sent out on HTTP protocal. It is as if it doesn't exist. This sounds like what is likely "stripping out" your cookie.
Cookie basics: If something is worth protecting via HTTPS and you need to track that info afterward (ie, authentication token), it is best to keep it in the HTTPS cookie and only access it from HTTPS.
This is a cookie security issue, and is better discussed at: Secure cookies and mixed https/http site usage

ASP.NET MVC FormsAuthentication.SignOut doesn't work

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.

Resources