I want to accept data from a client.
What are the pros and cons of each approach?
HttpServletRequest request = retriveRequest();
Cookie [] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if ("my-cookie-name".equals(cookie.getName())) {
String value = cookie.getValue();
//do something with the cookie's value.
}
}
or
String request.getHeader("header-name");
As I read How are cookies passed in the HTTP protocol?
Cookies are passed as HTTP headers, both in the request (client -> server), and in the response (server -> client).
getCookies, frees you from parsing the Cookie header string, and creating a java object out of it. Otherwise you will have to do something like:
String rawCookie = request.getHeader("Cookie");
String[] rawCookieParams = rawCookie.split(";");
for(String rawCookieNameAndValue :rawCookieParams)
{
String[] rawCookieNameAndValuePair = rawCookieNameAndValue.split("=");
}
// so on and so forth.
Related
I've got a Spring Boot application with some tests. The application's 'happy-path' requires that the user send a request to start a session, then it can make other requests to other services.
I'm trying to test these other services, but I need a session started first. My mindset was as follows:
Hit the session start endpoint
Get the session cookie from that request
Slap that cookie onto future requests made during testing.
To achieve that, I've got this mess:
String s = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie").get(0);
String[] split = s.split(";");
String sessionId = "";
for (String s1 : split) {
if(s1.contains("SESSION"))
{
sessionId = s1;
}
}
HttpHeaders headers = new HttpHeaders();
headers.add("SESSION", sessionId);
HttpEntity<?> httpEntity = new HttpEntity<>(headers);
RemoteDTOPacket= new RemoteDTOPacket();
packet.Token = UUID.randomUUID().toString();
String url = "http://localhost:" + port + "/domain/SomeFunction";
ResponseEntity<ResponsePacket> response = t.postForEntity(url, packet, ResponsePacket.class, httpEntity);
Assert.assertEquals(0, (long) response.getBody().count);
Obviously, this doesn't work and errors are thrown with abandon.
Does anyone know how to accomplish what I'm trying to do?
Any help is greatly appreciated.
Session id is stored in cookie that is stored in "Cookie" header - not in separate request header. Something like this should work:
List<String> coockies = t.postForEntity(loginUrl, remoteSessionPacket, String.class)
.getHeaders()
.get("Set-Cookie");
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.put(HttpHeaders.COOKIE, coockies);
HttpEntity<Void> requestEntity = new HttpEntity<>(requestHeaders);
Or you can get exact session id cookie that will be most probably stored under "JSESSIONID" key.
I have a simple web app with a Java API backend using JSP and Tomcat. How can I get the current logged in user (logged in via Azure AD)?
I'm trying this:
<%
// Fetch the data
URL url = new URL("https://myurl.azurewebsites.net/.auth/me");
Cookie cookie = null;
Cookie[] cookies = request.getCookies();
URLConnection connection = url.openConnection();
for(int i=0; i < cookies.length; i++) {
cookie = cookies[i];
connection.addRequestProperty(cookie.getName(), cookie.getValue());
}
// Convert to a JSON object
JsonParser jp = new JsonParser();
JsonElement root = jp.parse(new InputStreamReader(connection.getInputStream()));
JsonObject rootobj = root.getAsJsonObject();
String userID = rootobj.get("user_id").getAsString();
But this is getting a 401 Unauthorized error. However I can get the JSON from /.auth/me in the browser - presumably because it's sending the session cookie with it. Any ideas how I can fetch that JSON from my JSP?
According to the code you offered, I guess you want to receive the incoming cookie in the JSP and simulate the request URL https://myurl.azurewebsites.net/.auth/me to get JSON data.
However,you missed the Header part of the request, which is a necessary condition for Authentication of Azure Active Directory.
You could refer to the snippet of code as below and retry your request.
<%
// Fetch the data
URL url = new URL("https://myurl.azurewebsites.net/.auth/me");
Cookie cookie = null;
Cookie[] cookies = request.getCookies();
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
for(int i=0; i < cookies.length; i++) {
cookie = cookies[i];
connection.addRequestProperty(cookie.getName(), cookie.getValue());
}
Enumeration<String> headNames = request.getHeaderNames();
while(headNames.hasMoreElements()) {
String headerName = headNames.nextElement();
String headerVal = request.getHeader(headerName);
connection.addRequestProperty(headerName, headerVal);
}
out.println("generate connection.....");
connection.connect();
IOUtils.copy(new InputStreamReader(connection.getInputStream()),out);
%>
Hope it helps you.
I'm very new to Java Web programming and I am trying to write a method to authenticate a user, store a token in a cookie, and pass them onto the next page. I'm hung up on what the return type of the authentication should be. Should it return a Cookie object directly as the return value of authenticateUser()?
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response authenticateUser(#FormParam("username") String username,
#FormParam("password") String password) {
try {
// Authenticate the user using the credentials provided
authenticate(username, password);
// Issue a token for the user
_logger.log(Level.INFO, "----ABOUT TO LOG TOKEN TO WILDFLY");
String token = issueToken(username,"http://example.com","userToken",msInHour); //returns JWT token
_logger.log(Level.INFO, "----LOGGING TOKEN TO WILDFLY: ",token);
// Return the token on the response
//return Response.ok(token).build();
Response.createCookie(createCookie(token,username)).build();
} catch (Exception e) {
_logger.log(Level.INFO, "----ERROR in AuthService:",e);
return Response.status(Response.Status.FORBIDDEN).build();
}
}
private Cookie createCookie(String token,String uname){
//https://stackoverflow.com/questions/8889679/how-to-create-a-cookie-and-add-to-http-response-from-inside-my-service-layer
final Boolean useSecureCookie = true;
final int expiryTime = 60 * 60 * 24; // 24h in seconds
final String cookiePath = "/";
Cookie cookie = new Cookie("example.com", uname+"_"+token);
cookie.setSecure(useSecureCookie); // determines whether the cookie should only be sent using a secure protocol, such as HTTPS or SSL
cookie.setMaxAge(expiryTime); // A negative value means that the cookie is not stored persistently and will be deleted when the Web browser exits. A zero value causes the cookie to be deleted.
cookie.setHttpOnly(true);
cookie.setPath(cookiePath); // The cookie is visible to all the pages in the directory you specify, and all the pages in that directory's subdirectories
return cookie;
}
You seem to be using Jersey as your backend framework so you need to look at their documentation to see how setting cookies works. And no, you more than probably can't return the plain cookie as the browser won't understand it as such, especially since you're "producing" JSON.
How to set cookie in Jersey.
As you can see from the accepted answer the Response object should have a separate method for setting cookies, aptly named cookie().
I have some Java code which is calling a restful service, and needs to first authenticate and store cookies for a future call. I am using Jersey 1.8. The problem is that after making the call to authenticate, I try to retrieve the cookies using ClientResponse.getCookies() and iterate through the list of NewCookie objects. However, when calling NewCookie.getName(), the path of the cookie is returned.
The cookies returned in the response header look like this:
Set-Cookie: xsIdEEDB0766347B60DAEAA0AF57226EDD2C=385DF57B79FE0A4D84E04ED43000A81B; path=/; HttpOnly
My code looks something like this. I am just dumping the info to System.out for now because I wanted to look at the values in the debugger.
My question is why ClientResponse.getCookies() does not seem to work. Parsing the headers manually will work, but that just does not seem right. Is there a way to configure the Client or the ClientResponse to correctly get the cookies?
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
Builder builder = client.resource(MY_PATH).accept("text/plain");
builder = builder.header(AUTHORIZATION, auth);
ClientResponse response = builder.head();
if (response.getClientResponseStatus() == Status.OK) {
// Look at cookies in the response
List<NewCookie> cs = response.getCookies();
for (NewCookie c : cs) {
System.out.println(c.getName());
System.out.println(c.getValue());
}
// Look at the cookies in the header
List<String> cookies = headers.get("Set-Cookie");
for (String cookie : cookies) {
// example: xsIdEEDB0766347B60DAEAA0AF57226EDD2C=385DF57B79FE0A4D84E04ED43000A81B; path=/; HttpOnly
int x = cookie.indexOf(';');
String cookieNameValue = cookie.substring(0, x);
String[] nameValue = cookieNameValue.split("=");
NewCookie nc = new NewCookie(nameValue[0], nameValue[1]);
}
}
I'm trying to get cookie in servlet using
Cookie[] cookie = request.getCookies();
but cookie is always null.
So I set them from another servlet and they appear in browser preferences.
Cookie cookie = new Cookie("color", "cyan");
cookie.setMaxAge(24*60*60);
cookie.setPath("/");
response.addCookie(cookie);
I don't understand what's wrong?
According to docs getCookies() Returns an array containing all of the Cookie objects the client sent with this request. This method returns null if no cookies were sent.
Did you add the cookie correctly? If yes, you should be able to iterate through the list of cookies returned with
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {
String name = cookies[i].getName();
String value = cookies[i].getValue();
}
If no...
Cookies are added with the addCookie(Cookie) method in the response object!
SET COOKIE
Cookie cookie = new Cookie("cookiename", "cookievalue");
response.addCookie(cookie);
GET COOKIE
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for (int i = 0; i < cookies.length; i++) {
cookie=cookies[i]
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
}
}
Are you sure the client supports cookies? because if it is configure to NOT accept cookies, you will never get them back on a following request...
I had the same problem and discovered the cause in my case was that I was using the browser built into Eclipse. This does not accept cookies. When I accessed the same JSP from chrome, it worked. Perhaps you are doing the same thing I did?
It may also be the case that the browser you are using or your internet settings are set to reject cookies. Hope this helps you or any other visitor experiencing the same issue.
firstly ,you should create a cookie,and then add to response
Cookie cookie = new Cookie(name,value);
response.addCookie(cookie);