Problems with retrieving the correct cookie in Java - java

When I retrieve the cookies in my java servlet, all of the values from getPath() are null.
So if a cookie with the same name is set in directory /foo, and at the root directory, I retrieve two cookies with the same exact name, but I can't differentiate them because getPath() returns null for both.
I looked in firebug and saw that firefox was not sending anything for the path.
My application uses a "rememberme" cookie with the path set to "/". Everything works fine as long as there is only one cookie with name rememberme. But if somehow another cookie gets set with the same name on a different path like /foo, then my application won't know which one is the one I set for the root.
How can I differentiate the cookies? Do I need to worry about a cookie existing with the same name in a subdir, or can I just assume there will be only the one I set?

If the browser doesn't send a path, you should set the path to "/" in your Cookie handler.
Your server sets the cookies, not the web browser, so if you set all the paths for the cookies that you create to "/" for the same domain, you don't have to worry about it.

I'm not sure how much this will help you but I recently wrote this method to retrieve cookies from a URLConnection object and return them as a string:
public String getCookies(URLConnection connection) {
String headerName = null;
String cookie = "";
for (int i=1; (headerName = connection.getHeaderFieldKey(i))!=null; i++) {
if (headerName.equals("Set-Cookie")) {
if (cookie.equals("")) {
cookie = connection.getHeaderField(i);
}
else {
cookie = cookie + "; " + connection.getHeaderField(i);
}
}
}
writeToCookiesFile(cookie);
return cookie;
}
This method was being used in just a plain application though :) Hope it's of some benefit!

The browser will send cookies defined for path /foo only when the path of the url starts with /foo. If a cookie with the same name is set on both / and /foo, there is no way to distinguish them.

Related

Cookie cleanup not working with java code, I am trying to remove a cookie from parent domain

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.

HttpServletRequest returning no cookies - but they exist

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.

Cookie handling with Servlet

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.

Cookie not being read

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.

Get domain name in url with JSTL?

I am trying to get the domain name from the url with JSTL. The 2 methods I know return the wrong information. I need exactly what is in the URL.
When I do:
${pageContext.request.remoteHost}
I get my server's IP.
When I do:
${pageContext.request.serverName}
I normally get the right domain name, but on a server we have on amazon its returning "server1" instead of the correct domain name, probably because of the way it handles multiple domains.
Anyone know how I can get the current domain name in the URL?
I may need to get the URL and then parse it. How would I do that?
You should be using ServletRequest#getLocalName() instead. It returns the real hostname of the server. The ServletRequest#getServerName() indeed returns the value as set in Host header.
${pageContext.request.localName}
That's all. The solutions suggested in other answers are plain clumsy and hacky.
By the way, the ServletRequest#getRemoteHost() doesn't return the server's hostname, but the client's one (or the IP when the hostname is not immediately resolveable). It's obviously the same as the server's one whenever you run both the webserver and webbrowser at physically the same machine. If you're interested in the server's IP, use ServletRequest#getLocalAddr(). The terms "local" and "remote" must be interpreted from server's perspective, not from the client's. It's after all the server there where all that Java code runs.
You can parse domain name from URL
OR
public static String getDomainName(String url)
{
URL u;
try {
u = new URL(url);
}
catch (Exception e) {
return "";
}
return u.getHost();
}
You can use HttpServletRequest.getRequestUrl() to:
Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and server path, but it does not include query string parameters.
this would return a String like Get domain name in url with JSTL?
It should then be trivial to parse this to find the string that comes after the scheme (http, https, etc) and before the requestURI.
${pageContext.request.contextPath}

Categories

Resources