I have the following code running as part of a custom filter:
Cookie cookie = new Cookie("NAME", "VALUE");
cookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookie);
When running UT using Jetty server I receive the cookie successfully from the servlet.
Nevertheless, when I'm running a local Tomcat server (using IntelliJ), the cookie is not even set on the server side (i.e. not a client issue). The only cookie I can see is the jsessionid cookie.
I tried the following with no luck:
setDomain("")
setPath("/")
response.flushBuffer() after adding the cookie.
I'm printing all the response cookies right after I added the new cookie, but my cookie is not listed.
Collection<String> headers = ((HttpServletResponse) res).getHeaders("Set-Cookie");
for (String header : headers) {
System.out.println("Session Cookie:" + header);
}
I'm pretty new to web application and Java in general, so it is also possible that I missed something very basic.
Will appreciate any help here.
I found the answer here: http://www.coderanch.com/t/577383/jforum/response-addCookie-work-filter.
In short: "Adding a cookie requires modifying the HTTP headers of the response. Once the response has been "committed", e.g. anything written to the output stream, you can not modify the HTTP headers. The response has been committed by the time you try to add your cookie...Most JSP implimentations and some servlets will actually generate the response in a buffer. This means the response isn't committed the output is closed or manually flushed. So, this would work in some applications and not in others".
Bottom line, I needed to update the response before the chain.doFilter(req, res) has been called.
Related
I've browsed a bunch of questions that are similar to mine, but none of the solutions I have tried seem to work.
I have a Jersey2.0 REST service that adds a cookie to the response and returns it to an Angularjs front end application. I already have the setup done correctly (Access-Control-Allow-Credentials=true, no wildcard in Access-Control-Allow-Origin, etc..).
I do it by adding a "SET-COOKIE" header on the response like so:
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("SET-COOKIE", new NewCookie(cookieName, cookieValue);
This works, and I can see the cookie being returned in the response of that particular REST service call to that particular REST endpoint. What I mean is, on the Chrome developer console under the Network tab, I can click on the request that is supposed to return the cookie, and in both the 'Cookies' and 'Headers' tabs, I can see the cookie being returned in the response. In fact, when I make another request to the endpoint, that same cookie is now sent in the request and I can capture it on the Jersey server.
Great. The issue is that the cookie is not showing up on the 'Resources' tab. If I click on the 'Resources' tab, then along the left select the 'Cookies' dropdown and then select localhost, the cookie I'm trying to send in the response is not there. I'm assuming this is also why when I try to get the cookie in my AngularJs application via $cookies.get('cookieId'); using ngCookies, I get undefined.
Also, just in case someone mentions it in an answer/comments, I'm pretty sure the problem here is not HttpOnly. My JSESSIONID cookie gets returned, and I can see it in the 'Resources' tab with the Http field checked indicating HttpOnly.
I thought maybe because I'm in a corporate environment, they don't let me add cookies, but I'm able to do this on the Angular front end via $Cookies.put('cookieId', 'cookieValue'); and it shows on the 'Resources' tab just fine.
Any help as to why my cookies are not being added from the server?
After digging through a few more stackoverflow questions relating to my original one, I found out through this stackoverflow question that cookies that are created on one domain cannot be accessed on another domain using Javascript.
I will have to come up with a workaround for this, but my original question has been answered so marking this as answered.
For your case it is easy to solve if you just set the path of the cookie,
e.g.
Cookie myCookie = new Cookie("Name_of_cookie", "String_value_of_cookie")
myCookie.setPath("/the domain Js is using ")
Or just leave it as / for the main domain that most probably Js is deployed.
I am building a user tracking system for a web application. People could came from many urls. I want to know from which urls the came from.
I design url like this : http://www.example.com/ref/XXXXXXX.
I create a Filter to handle incoming request :
String cookieKey = "examplesite.cookie";
String cookieValue = referralIdentifier;
Cookie cookie = new Cookie(cookieKey, cookieValue);
cookie.setMaxAge(60*60*24*365);
((HttpServletResponse) response).addCookie(cookie);
HttpServletResponse resp = (HttpServletResponse)response;
resp.addCookie(cookie);
resp.sendRedirect("/");
When this code execute, I cannot see the cookie set in the browser.
If I change the redirect to forward, I can see the cookie.
The I see this blog post how to track people with cookie and redirect where the blogger suggest to use code to redirect.
So I changed my code and I replace resp.sendRedirect("/"); by
resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
resp.setHeader("Location", "http://www.example.com/");
Here I can see the cookie in Firefox but not in Chrome.
Is there a solution to track user after redirection ?
According to http://www.javamex.com/tutorials/servlets/cookies_api.shtml by default a cookie is visible to "requests to subpaths of the parent from which the cookie was set".
This might be your problem. To make the cookie visible on all paths, you can set the path to "/" using cookie.setPath("/").
I have a small confusion about Cookies, whenever the user is logging in we create cookies and adding to the response header.
Cookie cookie = new Cookie("sessionId", "232hghjghghgh"); // http cookie.
cookie.setVersion(1);
cookie.setPath("/");
cookie.setMaxAge(1000);
response.addCookie(cookie);
I think the above will be setting into the browser cache and we can get it from the browser cookies.
In our GWT module we already have an existing implementation like
Cookies.getCookie("sessionId"); // Cookies are from GWT
We are able to get the cookie using above line without using anywhere Cookies.setCookie() method.
Is that because of above line response.addCookie(cookie).
Could any body tell me, is my assumption correct?
Yes. Your first example is using a javax.servlet.http.Cookie, and this happens on the server side. The latter is purely GWT (i.e. client side) and returns java.lang.String (i.e. the String value of the cookie). But of course both are conceptually the same and setting one on the server will make the other show up on the client.
I have found a strange behaviour (strange for me, a novice :D) in my project.
Basicly after an action I create or update a cookie (if it exists or not) and send it to the client. The strange thing is that in the jsp I can read the cookie ONLY when I update its value (and I get the updated value, not the old one) but not the first time, when I create it (I can see the cookie using a browser tool but seems that the jsp can't read it).
Is this a normal behaviour? If yes, what do you suggest to do in order to have the cookie information available also at the first time?
Thanks very much!
Roberto
If you create or update a cookie, it will be stored in the response header. If you request a cookie, it will be requested from the request header.
I think your problem is that you're forwarding the same request from servlet to JSP and that you expect that the new cookie is already available in the request header. This is not true. The new cookie is only available in the subsequent requests.
You have 2 options:
Redirect to JSP. A redirect will create a new request.
Store the data of interest as request attribute and let EL in JSP access it.
By the way, I saw in one of your comments that you're using plain Java code to read cookies in a JSP. I would only say that using scriptlets in JSP is a bad practice. You can access cookie values easily in EL as follows:
${cookie.cookiename.value}
[Edit] oh my, now I see that this is an old topic. Hopefully my effors weren't all for nothing :/
Cookies are stored on client, and so if the response doesn't gets to the client yet, its value is not updated, but it should be available on the next requests.
cookies are used to identify clients when they send you any requests. here's what you are doing when you set the cookie up. you are sending the cookie to the client along with response. And when that client send his next request the cookie that you set comes along with it. so, in the jsp page where you are setting up the cookie, you don't have a request from the client with cookie! so you can't read it. but what you can do like what jerjer has said above. (i.e use a temp and store cookie's value in it and don't try to retrieve cookie. just read the temp value). And i see you say you can read the cookie only when you update. You will be able to read cookie's value from future reqests after cookie is set even if you don't update it. Hope this helps.
We have a JSF web application that uses Acegi security. We also have a standalone Java Swing application. One function of the Swing app is to load the user's home page in a browser window.
To do this we're currently using Commons HttpClient to authenticate the user with the web app:
String url = "http://someUrl/j_acegi_security_check";
HttpClient client = new HttpClient();
System.setProperty(trustStoreType, "Windows-ROOT");
PostMethod method = new PostMethod(url);
method.addParameter("j_username", "USERNAME");
method.addParameter("j_password", "PASSWORD");
int statusCode = client.executeMethod(method);
if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY ) {
Header locationHeader= method.getResponseHeader("Location");
String redirectUrl = locationHeader.getValue();
BrowserLauncher launcher = new BrowserLauncher();
launcher.openURLinBrowser(redirectUrl);
}
This returns a HTTP 302 redirect response, from which we take the redirect url and open it using BrowserLauncher 2. The url contains the new session ID, something like:
http://someUrl/HomePage.jsf;jsessionid=C4FB2F643CE48AC2DE4A8A4C354033D4
The problem we're seeing is that Acegi processes the redirect but throws an AuthenticationCredentialsNotFoundException. It seems that for some reason the authenticated credentials cannot be found in the security context.
Does anyone have an idea as to why this is happening? If anyone needs more info then I'll be happy to oblige.
Many thanks,
Richard
I have never done Acegi/SpringSecurity, but the symptoms are clear enough: some important information is missing in the request. You at least need to investigate all the response headers if there isn't something new which needs to be passed back in the header of the subsequent request. Maybe another cookie entry which represents the Acegi credentials.
But another caveat is that you in fact cannot open just the URL in a local browser instance, because there's no way to pass the necessary request headers along it. You'll need to have your Swing application act as a builtin webbrowser. E.g. get HTML response in an InputStream and render/display it somehow in a Swing frame. I would check if there isn't already an existing API for that, because it would involve much more work than you'd initially think .. (understatement).
In this case you can do Basic Authentication and set this header in every request instead of sending the jsessionid:
AUTHORIZATION:Basic VVNFUk5BTUU6UEFTU1dPUkQ=
The token VVNFUk5BTUU6UEFTU1dPUkQ= is the username and the password encoded base64.
Example:
scott:tiger
is:
c2NvdHQ6dGlnZXI=
One more thing: use SSL.