I'm in a journey of making a simple HTTP server using Java for educational purposes. I need to know how to instruct a client to save a cookie for identifying its session ID.
I've done my research and stumbled upon this and this which, despite being greatly informative and in fact introduced me to the whole CookieStore thing, does not really specify how to tell the client to save a cookie.
From what I've come to understand, the handle method in HttpRequestHandlers has only three parameter passed to it:
HttpRequest - the request itself along with some information about it.
HttpResponse - the "medium" as of where the response should be writen upon.
HttpContext - ... (Not really sure what it does, TBH.)
Meanwhile, all of the answers in the links I've stated above would call
response = client.execute(httppost, localContext);, or
HttpResponse response1 = httpClient.execute(method1, httpContext);
..at some point of the handling. I've no idea on how one could get a reference to the client (and thus execute the request to store the cookie).
What should I do? Am I missing something?
Cookie userCookie = new Cookie("Name","Value");
userCookie.setMaxAge(-1);//for a session cookie
userCookie.setPath("/");
response.addCookie(userCookie);//adds to cookie to the response that is sent to the browser.
Related
We are making use of this end point - https://www.googleapis.com/oauth2/v4/token
to get the access token.
We make use of apace HTTP classes to make a POST request to this end point in this way -
HttpPost httpPost = new HttpPost(GET_ACCESS_TOKEN_API);
StringBuilder blr = new StringBuilder().append(CLIENT_ID).append("=")
.append((String) accountCredentials.get(CLIENT_ID)).append("&")
.append(CLIENT_SECRET).append("=")
.append((String) accountCredentials.get(CLIENT_SECRET))
.append("&").append(REFRESH_TOKEN).append("=")
.append((String) accountCredentials.get(REFRESH_TOKEN))
.append("&grant_type=refresh_token")
.append("&redirect_uri=urn:ietf:wg:oauth:2.0:oob");
// The message we are going to post
StringEntity requestBody = new StringEntity(blr.toString());
// the default content-type sent to the server is
// application/x-www-form-urlencoded.
requestBody.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(requestBody);
// Make the request
HttpResponse response = HttpUtils.getHttpClient().execute(httpPost);
There has been a recent intimation from google to migrate from out-of-band as they have plans to deprecate this.
We make use of it this way as you can see in the code above -append("&redirect_uri=urn:ietf:wg:oauth:2.0:oob");
GET_ACCESS_TOKEN_API is https://www.googleapis.com/oauth2/v4/token.
I saw some posts mentioning that we have to replace this redirect_uri to localhost.
Can someone explain exactly how this works and what change needs to be done to migrate this successfully ? I tried searching through the documentation to see if there any sample examples but couldn't find anything that matches our use case.
I am referring to this site -
https://developers.google.com/api-client-library/java/google-oauth-java-client/support
I tried to browse through samples, guides, but it mostly talks about different API's. I didn't find the github links that much useful.
Any help would be much appreciated.
Similar to the already existing question Apache HttpClient making multipart form post
want to produce a http request, holding a file and a key=val pair.
Currently the code looks like:
HttpPost post = new HttpPost("http://localhost/mainform.cgi/auto_config.htm");
HttpEntity ent = MultipartEntityBuilder.create()
.addTextBody("TYPE", "6",ContentType.TEXT_BINARY)
.addBinaryBody("upname", new File("factory.cfg"),ContentType.APPLICATION_OCTET_STREAM,"factory.cfg")
.build();
This is simply applied to HttpPost object as entity and passed to the client.
Which is sent to a linux-type device (blackbox) with a lighthttp service running. The problem is that when I send this request I do not see a response from the device(physical, and the HttpEntity always returns a default 200 OK).
Through Wireshark I've noticed two differences, on which i would really appreciate to get some help:
1. The multipart elements have an additional header(comparing to the original request) - Content-transfer-encoding, which i assume may be the reason of the fail.
2. Content length differs drastically.
So the first question would be - how to deal with the Encoding?
Found the point, on which it was failing. Needed this addition:
.addTextBody("TYPE", "6",ContentType.WILDCARD)
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE).setCharset(Charset.forName("UTF-8"))
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.