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.
Related
Is there a way to set a cookie for a website I'm trying to redirect to? I'm trying to use Spring redirect to achieve this but I think I'm doing something work (or this is not possible at all)
Here's the method I have tried to use:
#GetMapping("/redirect")
public void redirect(HttpServletResponse response) throws IOException {
Cookie testCookie = new Cookie("test-cookie", "blah");
testCookie.setDomain("something.com");
testCookie.setPath("/");
response.addCookie(testCookie);
response.sendRedirect("https://something.com/test.html");
}
I can see the "set-cookie" header but no actual cookie seems to be set in my browser.
M
Encountered same problem. My case was to pass redirect from backend to frontend with attached cookies. Within one main domain. There's no success with code
cookie.path = "/"
cookie.domain = "domain.com"
cookie.maxAge = 60
cookie.isHttpOnly = false
response.addCookie(cookie)
But everything run when I changed to
response.setHeader("Set-Cookie", "customCookie=value; Path=/; Max-Age=60; Domain=domain.com")
Important: cross-domain cookie passing will be blocked by browser
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'm trying to invalidate/expire an insecure cookie from a securely accessed servlet and send a redirect back to the client. However, when the redirect is followed, the request still contains the original, unexpired, uninvalidated (is that a word) cookie.
Here's a more detailed description of the flow:
1) Client requests a particular insecure url backed by Servlet A.
2) Servlet A detects that there is a Cookie XX and redirects to a secure url backed by Servlet B
3) Servlet B does its magic, then invalidates Cookie XX by setting the MaxAge to 0 and redirects to Servlet A via an insecure url.
4) In Servlet A, I'm still able to access the cookie just as it was in the first request.
Can anyone lend a hand? I was under the impression and can't find evidence to the contrary that when a cookie is sent back with a redirect response, it is still processed before the new request is sent out. This is happening in all browsers (Chrome, FF, IE) that I have access to, so I don't think its a browser thing. In HTTPFox and the Chrome Developer tools I can see the original cookie getting sent in the first and second request, the invalidated cookie coming back in the response to the second request, and the original cookie being sent again in the third request. I've tried setting the MaxAge to 0, setting the value of the cookie to null/empty string, and another value but it never changes. All of the server side code is done in Java if it matters.
Help is very much appreciated.
Have you tried making sure that the domain and paths for the invalidated cookie is the same as the original cookie?
Also, a better way to handle sensitive cookies is setting the 'secure' flag on the original cookie. That will tell the browser to never send the cookie over an insecure connection.
This turned out to be an oversight on my part. When Servlet B invalidated Cookie XX, it also set the cookie's path to something other than what it originally was. That, in effect, created a Cookie XX-B and had no effect on the original Cookie XX. Making sure my cookie's paths were the same fixed it.
In two separate projects I've had to invalidate a cookie. This is what I have had to do:
Get the cookie in question from the HTTP request object
Set cookie max age to by invoking Cookie.setMaxAge(int).
Call the Cookie.setPath(String) method, even if path is to remain the same
Add the cookie back into the HTTP response object, I.e. HttpServletRespons.addCookie(cookie)
Only after executing all the steps above did the browser stop passing the cookie back to server on subsequent requests.
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.
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.