I am having a problem of setting the data of a (persistent/cross browser session) cookie correctly inside a Servlet and the reading it in a Filter.
the code of the Servlet (running at log-in time) is:
String encodedValue = new String(Base64
.encodeBase64(req.getParameter("account").getBytes()));
Cookie cookie = new Cookie("projectAuthenticationCookie", encodedValue );
cookie.setMaxAge(24*60*60);
cookie.setPath("/");
res.addCookie(cookie);
This will get the cookie inside the response, but the when I read it within my filter with the following code:
Cookie authenticationCookie = null;
Cookie[] cookies = ((HttpServletRequest) request).getCookies();
for (Cookie cookie : cookies){
if ("projectAuthenticationCookie".equals(cookie.getName())) {
authenticationCookie = cookie;
}
}
I only get the value I set right, all other fields are either null, empty or different. Max age for example always returns -1 and thus the cookie will never persist.
I tried setting the expires-header with:
res.setDateHeader("Expires", System.currentTimeMillis() + 24*60*60*1000);
as I read that without a valid expires-header the session will timeout anyway (correct me if I am wrong), but that didn't help either...
One issue I am thinking of is that I am running on localhost (tried setting cookie.setDomain("localhost") but also no luck). My web server/serclet container is Jetty 7 but I do not think that this is relevant...
Any hints?
The fields other than name and value are not populated (and thus not meaningful) on cookies you get from a request.
These fields are intended to inform the browser about the max age; path, etc. of the cookie, but the browser doesn't send back this information to the server. The only time where it's important to have the correct max age, path, etc. is when you create a cookie and add it to the response. Use your browser to check if it stores the correct information instead of trying to find it at server-side.
Related
I am stuck in cookie clean up issue.
We have created cookie value with domain : .www.parent.com
And later we changed code base to create cookie values in domain : .parent.com
This is giving us cookie values from both the domains and messing up with our code. Is there a way to delete cookies from .www.parent.com via java code ?
I have already tries doing like this :
Cookie cookie = new Cookie("oldCookie" , null);
cookie.setMaxAge(0); or cookie.setMaxAge(-1);
cookie.setPath("/");
response.addCookie(cookie);
You might want to get all the cookies the client has stored and check them, using request.getCookies(), which returns a Cookie array.
In that way, you'll need to check anyone for the wanted domain and set its TTL with something like this:
Cookie[] c=request.getCookies();
for(int i=0;i<c.length;i++){
if(c[i].getDomain().equals(".www.parent.com")){
c[i].setMaxAge(0);
response.addCookie(c[i]);
}
}
This way, the cookie you're passing to the response should have exactly the same name, path and any other attribute except for maxAge value being 0.
We have a portlet based application that retrieves a certain cookie for validation and then sends off an action request afterwards.
However, we're seeing an issue where the HttpServletRequest is returning a null list of cookies - even though I can 100% confirm there are cookies. In fact, sometimes the code DOES work and shows the cookies (although this is pretty rare).
We've noticed that IE appears to work more frequently than FF and Chrome, but again, there's no consistency or pattern really to determine what causes it to function.
The Request is always obtained - there's never an issue here of a null pointer. The only issue at this moment is that the cookie list is empty.
Method in static class that returns HttpServletRequest
FacesContext context = FacesContext.getCurrentInstance();
Map<String, Object> requests = context.getExternalContext().getRequestMap();
for (String requestName : requests.keySet()) {
if (requests.get(requestName) instanceof HttpServletRequest) {
return ((HttpServletRequest) requests.get(requestName));
}
}
return null;
Call from the other class to the static method above:
Cookie[] cookies = StaticClass.getHttpRequest().getCookies();
System.out.println("Cookies = " + cookies);
The HttpServletRequest method getCookies() should return an array of cookies the client sent in on the request. If the array returned is null, it means that the request the client sent in contains no cookies. Did you call addCookie(yourCookie) method within the same domain or subdomain (I ask as you cannot access cookies across different domains)?
ie:
Cookie yourCookie = new Cookie(name, value);
response.addCookie(yourCookie);
If the cookie was not added to a previous response, it will not be on the request.
Some other clues:
Check your Cookie's max age. Cookie may be expired.
Check the domain of the cookie and the domain of the request URL. If you are not sure, post them here for help.
In general if you can capture the http request message and post it here it will also be helpful.
Update: in firefox you can right click a page, and select 'view page info', then select the 'security' tab, click the 'view cookies' button to view all the cookies. You can also change the domain name in the popup window to see the cookies under other domain.
We have the following situation:
JSESSIONID is being sent by both cookies and URL, but because of a Adobe Flash BUG, they are different (actually, the cookie JSESSIONID is wrong).
What we would like to do is to use the URL JSESSIONID instead of the one sent in the cookies. In other words, when I execute request.getSession(), it should return the HttpSession associated to the ID in the URL and not in the cookie.
We looked into Tomcat7 source code and, in fact, Tomcat first parses the URL, searching for an identifier. Then it overrides it with cookies SESSIONID if they are present. Here is the code snipped in CoyoteAdapter.java (tomcat 7.0.26):
String sessionID = null;
if (request.getServletContext().getEffectiveSessionTrackingModes()
.contains(SessionTrackingMode.URL)) {
// Get the session ID if there was one
sessionID = request.getPathParameter(
SessionConfig.getSessionUriParamName(
request.getContext()));
if (sessionID != null) {
request.setRequestedSessionId(sessionID);
request.setRequestedSessionURL(true);
}
}
// Look for session ID in cookies and SSL session
parseSessionCookiesId(req, request);
parseSessionSslId(request);
We could disable cookies JSESSIONID at all, but we can't because we use it for all URLs in the website. We'd like to disable cookies for JUST THIS SPECIFIC URL.
Is it possible? Is there any other idea or workaround to solve this problem?
You could implement a custom servlet filter that would replace request, response and session objects with your own wrappers. The wrappers then can behave differently based on the URL, e.g. delegate or not to the original session instance. Though you won't be able to access session data for some other id, without changing Tomcat code.
I implemented "Remember me" functionality in my web app. I did this using a cookie that contains username/password encrypted using RSA.
I add the cookie when I login; if then I logout (without closing browser) the cookie is read ok and in the login page I see username/pass already typed.
But if I close the browser; or close tab and run the application again, when the cookies are read, the only cookie that is read is the JSESSIONID. the cookie with the credentials is not in the array returned by
((HttpServletRequest)facesContext.getExternalContext().getRequest()).getCookies();
even though I can see it in the browser. why is that?
This is the code that creates the cookie:
String credentials = username + "?" + password;
Cookie c = CookieHandler.getInstance().createCookie("vtcred", credentials, rememberMe);
FacesContext facesContext = FacesContext.getCurrentInstance();
((HttpServletResponse) facesContext.getExternalContext().getResponse()).addCookie(c);
and method createCookie:
public Cookie createCookie(String name, String value, boolean rememberMe) {
value = encript(value);
Cookie credCookie = new Cookie(name, value);
credCookie.setHttpOnly(true);
if(rememberMe) {
credCookie.setMaxAge(86400);
}
else {
credCookie.setMaxAge(0);
}
return credCookie;
}
Edit: I am setting the cookie's max age to one day; and in the browser I can see that the cookie expires tomorrow, so that's not the problem
Thanks in advance,
Damian
edit2: this is very odd, but it seems to be working now. I'll keep testing it and notify. Thanks.
I found why sometimes a cookie is not read. It has to do with the path attribute.
If anyone is having this issue, set the path of the cookie, like this:
Cookie c = new Cookie("name", "value");
cookie.setMaxAge(86400);
cookie.setPath("/");
Regards
You might want to set the cookie with an expiration date. If you dont , it will only last as long as the browser session.
I'm having an issue using the Cookie class of the Servlet API 2.5 on Tomcat . I pull out the list of cookies from the HttpServletRequest object and iterate over them like so:
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies) {
System.out.println("Name=" + cookie.getName() + " Domain=" + cookie.getDomain());
}
However, for every single cookie in the request the Domain is null. Why is this? The reason I'm asking is because I have a cookie with the same name in two different domains and I want to be able to differentiate between them based on the domain. To help clarify the situation, my identically named cookies are being set in .anydomain.net and .subdomain.anydomain.net. Both are getting sent in the request but the domains are null when they get to the servlet. Is it expected behavior that the servlet cannot see the domain of cookies sent to it?
Edit: I set the cookies along with domain,expiration,and path in a previous request to the servlet. The next request coming into the browser with these cookies shows the domain as null. I have verified the cookies are getting set in the right domains in the browser.
Edit 2: I'm using Tomcat 6
Are you sure that you can get anything except the value from request cookies?
The browser will send only name=value in the HTTP Cookie header.
Other attributes (secure, domain, path, expiration) are only available for cookies that you set into the response yourself.
They are used to create the Set-Cookie response headers.
Properties such as domain are only used for a cookie when it is a part of the response (i.e. in Set-Cookie header). A client (such as a web browser) should only send the cookies that have the correct domain (path, etc.). The request thus only sees values because the header itself (Cookie) only contains values. Your client should not be sending cookies from different domains to the server.