I read that a page which runs under an https connection cannot share an InProc Session (based on cookies) with another page (or the same for that matter) running under regular http. My site is running on Server 2003, IIS 6 and .Net 2.0.
After some experiments it appears that a page which stores data in session while being connected through https CAN subsequently access the data even if running under plain http.
So, is it possible or should I go over and look for flaws in the SSL configuration?
From MSDN:
When a user moves back and forth
between secure and public areas, the
ASP.NET-generated session cookie (or
URL if you have enabled cookie-less
session state) moves with them in
plaintext, but the authentication
cookie is never passed over
unencrypted HTTP connections as long
as the Secure cookie property is set.
So basically, the cookie can be passed over both HTTP and HTTPS if the Secure property is set to false.
I have avoided this issue by adding this to my Global.asax file:
void Session_Start(object sender, EventArgs e)
{
if (Request.IsSecureConnection) Response.Cookies["ASP.NET_SessionID"].Secure = false;
}
This means that if the Session cookie is created over HTTP, it will only be accessible over HTTPS.
IIS setting
In the IIS properties window, under the ASP tab –> Session Properties, there is a setting for “New ID on Secure Connections”
I fixed this intermittent issue for myself by setting this to false.
Searching for the problem doesn't turn up much chatter about it so far, still looking.
Edit: okay finding some stuff now.
Right it seems that it will work fine if both sets of pages are in the same application/website.
So I'd go ahead and carry on, feeling reassured.
If any of the above solution does not work try this. I have cracked this out after doing research of a couple of days.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
...
...
CookieSecure = CookieSecureOption.Never
});
Related
I am developing an application that requires the user to select a client certificate to authenticate, and do so by overriding the OnSelectClientCertificate method of the browser's request handler.
On initial authentication this works fine, but I want to be able to allow the user to logoff while keeping the application open and reauthenticating with a different client certificate. the problem is that OnSelectClientCertificate never seems to be called again. Have tried deleting all cookies and calling CloseAllConnections but still no luck.
Does anyone know the solution to this?
did manage to find a solution to this problem, it is as amaitland said that the certificate selection was cached per RequestContext, so to get it to prompt again I moved away from using the global RequestContext and instead used a new RequestContext whenever I needed to prompt for a client certificate again.
Internet explorer is not keeping my authentication cookie after one page redirect.
Here is the situation:
I have an ASP.NET 2.0 web application running on a shared iis7 hosting. The application uses forms authentication to handle login and user identity and writing a cookie (.ASPXFORMSAUTH) on the client machine for that purpose.
in IE (checked with version 8, 9), from some locations, the authentication cookie is not being kept after the first page. The observed behavior is:
User name and password are submitted in login form
User is succesfuly redirected to the first-after-login page (and fiddler shows that the .ASPXFORMSAUTH cookie exists)
After clicking another link or hitting F5 for refresh, the user is credirected to login, and the authentication cookie (according to fiddler) doesn't exist anymore.
at the refresh / click, the authentication cookie is missing in the request headers.
This doesn't happen in Chrome / FF, and even in IE, it seems to be dependent on the location from which I am connected.
also, locally (using the internal dev server in VS2008), all works fine and reflects fine in fiddler as well.
I am banging my head at it for a few days now. Thought it may be some kind of a strange firewall problem, but couldn't determine anything conclusive.
Ideas will be appreciated.
IE suffers from a weird bug - for some reasons, if there are non-alphanumeric characters in the domain's name, IE won't persist cookies... and hence you'll have no persistent session between different calls.
Check if your domain has non-alphanumeric characters in it, such as test_domain or test-domain or the likes. Unfortunately, I don't know any fixes for this short of aliasing the incriminated domain or accessing it directly via the IP. The reason you've got no problems locally is that you're pointing to http://localhost, which is fine. As soon as you deploy to a non IE compliant domain you'll witness the problem.
Happened to me and it took hours to find out why. Hope this helps. Another reason to kill IE with fire.
My solution has been a combination of other solutions:
IE not saving asp.net authentication token / cookies
http://connect.microsoft.com/VisualStudio/feedback/details/662275/asp-net-user-agent-sniffing-and-ie10-internet-explorer-10
upgrade to .NET 4.0 adding the tag ticketCompatibilityMode="Framework40" in the web.xml: http://msdn.microsoft.com/en-us/library/1d3t3c61.aspx
Note that the real final solution was the 3rd.
Last but not least: once I set this flag above I had to change the logout method in the code behind because the old one did not logout any more:
protected void LoginStatusLink_LoggedOut(object sender, EventArgs e) {
// remove the authenticatation cookies from the browser
FormsAuthentication.SignOut();
// force a new 'expired' auth cookie
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName);
cookie.Expires = DateTime.Now.AddMonths(-1);
Response.Cookies.Add(cookie);
// delete roles cookie
Roles.DeleteCookie();
// clear and abandon session
Session.Clear();
Session.Abandon();
// this line just to leave (forget) the current page
this.Response.Redirect("~/");
}
1.try to create a persistant cookie
2.check your cookie settings for IE
Check the server's date. I had a situation where the server was 1 day behind the browser and so the authentication cookie essentially expired immediately. This affected IE, but not FF.
my question upfront is:
When changing from http to https: How do I enforce on Tomcat that the value of the JSESSIONID / (i.e. the session cookie) gets changed?
Here's my situation:
I assume we are having a potential security issue in our application and wonder how to fix it.
We run a JSF1.2 / Seam2 application inside of a Tomcat 6.x and force the usage of session cookies (no sessionid in URLs).
We allow http access, but when a user logs in we switch to https and stay on https.
We also do have a Filter that adds 'secure' to the cookie whenever the request is coming through https to ensure that the session cannot go back to http.
(somehow I thought Tomcat would do that automatically)
I noticed that the JSESSIONID doesn't change when switching between http and https.
This suggests to me that an attacker could potentially spy out the session cookie through http and then hijack the session.
So how can I tell Tomcat to use a different JSESSIONID when changing to https?
(Or if thats the default behavior: What could lead to this not happening anymore?)
Thanks for any hints/ideas!
some time (years actually) I posted this filter here that we use to renew the session ID after the login:
https://issues.jboss.org/browse/JBSEAM-2450
We call newSession() just after a login to mark the session-ID to be renewed on the next GET request (POST requests don't work well due to the restore of the view state, but the POST/REDIRECT/GET with Seam will issue GETs quite often).
You might want put it into your filter -- or you just mark your session to be refreshed in the next GET request. Just make sure that you don't renew your session when processing a JSF POST request.
Someone else also provided a Tomcat Valve to solve this
Best regards,
Alexander.
Quick summary
Pinging back to a webservice in ajax from the client keeps the user's session alive, I don't want this to happen.
More extensive summary
For a website we're developing, we need the client to ping back (in js) to a webservice (ASMX) on the server (IIS7.5). This happens to let the server know that the user is still on the site, and hasn't browsed away to another site.
This is as our customer wants to let users lock records, but if they browse away to other sites, then let other people take over those locked records. Perhaps the distinction between the client being on the site but inactive and on another site seems unimportant, but that's kinda irrelevant, I don't get to write the UI spec, I just have to make it work.
My problem is this, the ping stops the user from being timed out on the server through the standard forms authentication timeout mechanism. Not surprising as there is that 30 second ping in the background keeping the session alive. Even though we want to know if the user is still on the site, we want the normal forms authentication timeout mechanism to be honoured.
I thought I might be able to fix this by removing the ASP.NET_SessionId and .ASPXAUTH cookies in the XMLHttpRequest that is the server ping, but I can't figure out how to do this.
This is how my web service & method are defined:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class PingWS : WebService
{
[WebMethod]
public void SessionActive(string sessionID)
{
// does stuff here
}
This is how I'm calling it in js (request is over HTTPS, :
$.ajax({
type: "POST",
url: "PingWS.asmx/SessionActive",
data: 'sessionID=' + aspSessionID + '}',
beforeSend: function (xhr) {
xhr.setRequestHeader('Cookie', '');
xhr.setRequestHeader('Cookie', 'ASP.NET_SessionId=aaa; .ASPXAUTH=bbb;');
},
dataType: "json"
});
I was trying with the setRequestHeader, but that just appends to the header rather than overwrites the header, and IIS is happy to ignore that junk I added.
I'm thinking maybe I should be trying to do this at the server end, someone take PingWS.asmx out of the loop so that it doesn't keep the session active, but I'm not sure how to do this.
Although the title of the question is focused on clearing the cookie in the header, I'd be super happy if anyone points out that I'm being really stupid and there is actually a much better way of trying to do what I'm doing.
I'm thinking at this stage maybe I need to add something to the webmethod that says how long this particular page has been inactive, and use that knowledge to timeout manually. That actually sounds pretty easy, so I think I'll do that for now. I'm still convinced that there must be an easy way to do what I originally wanted to do though.
Update
I'm thinking I'm pretty screwed in terms of cookie manipulation here as both the .ASPXAUTH and ASP.NETSessionId cookie are HttpOnly, which means the browser takes them out of your hands, you can't access them via the document.cookies object. So I would say that leaves me with:
Updating my SessionAlive webmethod to track each request so I can tell how long the user has been sitting idle on a page and timeout if needs be
Marking the .asmx page somehow on the server end so that it's taken out of the normal authentication/session tracking flow
I know how to do 1. so I'll start there but 2. seems much cleaner to me.
You could restrict the authentication cookie to a given Path:
<authentication mode="Forms">
<forms path="/admin" />
</authentication>
This way the authentication cookie will only be sent to the /admin portion of your site and if you put your web service at the root you can ping it with AJAX without sending the cookie.
Another option is to simply host this webservice into a separate virtual directory.
As you're finding you're out of luck with client cookie manipulation (or clientanipulation of any kind). Manipulating headers might be possible but you'd have to intercept the traffic very early in the pipeline. I don't even know if it will be possible in the service itself but a traffic manager like Zeus could do it. I don't believe it's possible to configure the session engine in such a way as to ignore a given combination of endpoint and client request and although it should be possible to replace the entire session engine that will be undocumented and extremely time consuming I'd think.
Basically you need to manipulate traffic before it touches the service or you're not going to resolve this. Session was not designed to be variant.
There is a server side answer. Basically you disable sliding timeouts on forms authentication, then manually slide the timeout yourself, and skip it for the ping.
Pretty easy for me as every page uses the same root Site.Master and all pages inherit from the same base class.
Summed up here:
http://picometric.blogspot.com/2009/04/manual-sliding-expiration.html
I can't seem to find the one right answer to my problem. I'm being overwhelmed with information I'm finding on the internet, and I have no idea what I should do.
My setup is as follows : Apache server (front end), Tomcat 6.0 (back end), RapidSSL certificate is on the Apache server, my site is made up of Java Server Pages.
The problem :
I have a few pages that are under https, while the rest of the site pages are under http.
The login page I have, is under https, and I've noticed that when I login, and redirect to an http page, that the session is not being maintained. Its creating a new one, which results in the user being sent to my 'session expired' page, when really, upon a successful login, they would be redirected to a different page.
Questions:
Why is the session not maintained when switched from https to http?
How do I fix this problem?
I need the session attributes that are created on the http pages, to be present on the https pages, so when the user is then directed to an http page again, the session hasn't been recreated, and the attributes lost.
Please ask me any questions you feel are necessary in order to help me figure this out. I greatly appreciate any help I receive. This issue has become a stumbling block for me, especially since I obviously lack the 'expertise' to figure it out myself.
Allowing the user to use the same session after logging in is a security vulnerability. Tomcat by default does not allow sessions to migrate from SSL to non SSL pages.
You should change your logic so if a user is doing a login, the session is silently updated, and logged in instead of going to the session expired page.
It's likely that you're using "secure cookies" to maintain the session: these cookies don't propagate from HTTPS to HTTP. This is generally a good thing.
You can chose not to do this, but when you transfer a session from HTTPS to HTTP you have to take extra care that you don't allow it to be reused over HTTPS later, as it may have been compromised.
Are you using a simple reverse proxy to connect to Tomcat? If that's your case, use mod_proxy_ajp to use AJP to connect Apache HTTP Server to Tomcat Application Server.
I have the same issue, where some parts of the site are https, and some are http. I've found that with Tomcat, session cookies created over http carry over to https no problem, however session cookies created over https are lost when moving to http.
One solution I have found maintaining a session as the user travels the site, is to bounce the user around when they first arrive. I created a RequestFilter with the following code:
if (request.isSecure() && session.isNew()) { // session cookie created over ssl
try { session.invalidate(); }
catch (Exception e) { /* handle error */ }
String url = request.getRequestURI().replaceFirst("https", "http");
response.sendRedirect(url);
}
else if (!request.isSecure()) {
String url = request.getRequestURI().replaceFirst("http", "https");
response.sendRedirect(url);
}
This forces new sessions to non SSL to create a lasting session cookie, and then once a session exists, the user forwarded back to secure request. This results in the session staying alive.
Or here's an options that involves less bouncing around, just overwrite the session cookie with one that isn't secure:
if (request.isSecure() && session.isNew()) {
Cookie c = new Cookie("JSESSIONID", request.getSession().getId());
c.setSecure(false);
response.addCookie(c);
}