Session management in Dropwizard 0.8.x - java

Can someone give me insight of how do I implement session management in Dropwizard 0.8.x or above. I was using Dropwizard 0.7.0 till now and working perfectly in it. But I really confused by change docs provided when I migrated to 0.8.x.
In Dropwizard 0.7.0 (which I was using previously) it was done like the following
/*MainApplication.class session handler */
environment.jersey().register(HttpSessionProvider.class);
environment.servlets().setSessionHandler(new SessionHandler());
/*Resource.class session check*/
HttpSession session = httpServletRequest.getSession(true);
But it does not seems working anymore, precisely saying HttpSessionProvider.class is not there and replaced by some other implementations.
It would be really helpful someone show to what this is changed to.
Thanks.

The reason this isn't working for you is because you need to set the cookie in the response. I noticed this while looking into enabling session state for a dropwizard application where the underlying cookie gets created on the Jetty Response object but it never makes it's way onto the Jersey Response object and therefor gets dropped.
What I've done to work around this issue is to implement a Filter that extracts the "Set-Cookie" information from Jetty and puts it onto the outbound response object.
String cookie = HttpConnection.
getCurrentConnection()
.getHttpChannel()
.getResponse()
.getHttpFields().get(HttpHeader.SET_COOKIE.asString());
if (LOG.isDebugEnabled()) {
LOG.debug("Adding session cookie to response for subsequent requests {}", cookie);
}
httpServletResponse.addHeader(HttpHeader.SET_COOKIE.asString(), cookie);

#Yashwanth Krishnan
I know this is old but I noticed that the session was not maintained from one URL to another, simply add this code when you init the application, session handling is mostly a container thing and not specific to DropWizard.
SessionHandler sessionHandler = new SessionHandler();
sessionHandler.getSessionManager().setMaxInactiveInterval(SOME_NUMBER);
/**
* By default the session manager tracks sessions by URL and Cookies, we
* want to track by cookies only since
* we are doing a validation on all the app not URL by URL.
*/
sessionHandler.getSessionManager().setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
environment.servlets().setSessionHandler(sessionHandler);

Related

Using Vert.x `AuthenticationHandler` from vertx-web, we hit the authentication provider for every call?

I'm using Vert.x for my web service, where a part of it required authorization. I've set an AuthenticationHandler (using the OAuth2 implementation from vertx-auth-oath2) to listen on the protected paths (lets say "/*") and it is correct called, sends a redirect to the authentication provider, which redirects back and then correctly to the real handler. This works fine.
But the next time we call the protected endpoint - it does the whole thing again. I see that in the abstract AuthenticationHandlerImpl class it checks if the context already has a user() and if so - will not run the actual auth handler, which is the behavior I need - but it obviously doesn't happen because every call is a new request with a new RoutingContext.
What is the "correct" way to retain the User object across requests, so that the auth handler will be happy?
I'm guessing it has something to do with session storage but I've never used that - up until now I was using a custom "API key" style solution, and I'm trying to do this "The Right Way(tm)" in this new project.
I'm using the latest Vert.x 4.3.5.
You will need CookieHandler and SessionHandler to store and handle session with user. This will work out of the box with provided vertx-auth-oath2.
Here is a simple example to get you started:
https://github.com/vert-x3/vertx-examples/blob/master/web-examples/src/main/java/io/vertx/example/web/auth/Server.java

Dynamically change domain of JSESSIONID cookie?

How can i dynamically change the domain of the JSESSIONID cookie that tomcat or jetty generates?
I stumbled accross this one:
Sharing session data between contexts in Tomcat
But i need to do this on request basis (the above is on context basis).
For example:
request1 comes from www.testdomain1.com and needs the domain ".testdomain1.com".
request2 comes from www.testdomain2.com and needs the domain ".testdomain2.com".
The domains are not known at deploy time and can change any time.
I used a simple servlet filter with a HttpServletResponseWrapper for cookies from my application, but JSESSIONID doesn't get intercepted by the filter (it's not generated by the webapp but by the container).
[edit] can't go the httpRequest.getSession().getServletContext().getSessionCookieConfig().setDomain() way, cause it seems the sessioncookieconfig is readonly after the context is initialized..
[edit] can't go with a tomcat valve cause the response is already commited (isCommitted is true). In addition tomcat doesn't use reponse addCookie or header methodes to set JSESSIONID cookie. And Response class is final so not wrapper can't be created for that one.
[edit] with jetty a custom SessionHandler is not working either, cause there is no access to the request object.
I highly suspect this entire thing is impossible. The only solution i can see is to put a proxy in front of the servlet container and change the cookie this way, but that is overkill.
In the next request that is after the session is created, get all the cookies
Cookie[] c = request.getCookies();
//for loop{
if(c.getName.equals("JSESSIONID")){
c.setDomain("....);
}
}

How to initialise a session in Play

Well, this is from a developer newly using Play. When it came to using session, I found its not at all like I have been doing in servlets or jsps.
I have tried reading documentation and found session in Play are stored in HTTP cookies rather. I have tried importing HTTP class of play.
My problem however is I am unable to initialise a new session to set values in it.
I have obviously tried using 'new' session as in Java and that obviosly didnt work out.
Session session = new session();
Also after looking somewhere I have used:
Session session = Http.Context.current().session();
which shows me error in identifying context and current
I have tried looking at sample codes and codes on net. each of them however is different and I don't get the basic way of using sessions in Play, so that after that I can use put and get to keep and retrieve.
I know the question seems too basic but believe me there is no exact answer available anywhere to what I need. So please help me regarding this.
Any answer, any piece of code, or any Link on this will be highly appreciated.
Forget everything about the sessions from the jsp and servlets world while working with the Play's session. Play doesn't store anything on the server side and by design it's completely stateless. The Play session is just a cookie attached to every http request and it's stored on the client side. Word 'session' may be misleading in your case.
Working with the session is pretty straight forward. All you need is inherited from play.mvc.Controller which you have to extend when creating your own controller. To put a value in it you simply call the session(String key, String value) method from within a controller. For example:
public class Application extends Controller {
public static Result login() {
session("key", "example value");
return ok("Welcome!");
}
}
If there is no session cookie stored on client side this method will create new one and attach it to the HTTP response. Otherwise it will modify the existing one.
To read stored value use:
String value = session("key");
You can also remove value from the session:
session().remove("key");
or completely destroy it:
session().clear();
These are helper methods to work with the particular cookie witch in Play's terminology is called session. Nothing stops you from creating another cookie with similar purpose. But it'll require more writing. These helper methods saves your time and in many cases are more than enough.
You can specify session cookie name in your application.conf by setting session.cookieName property.
In play 2.8 the Http.Context was deprecated. This means, among other things, that the method "session()" is no longer available in a controller.
This is the updated way of doing it:
public Result info(Http.Request request) {
//This is the equivalent to the old session()
request.session() ...
}
The Http.Request needs to be passed down through the route defined in routes. More information here.

Confusion about how java web session handeling works. Demystifying Cookies and Header differences using servlet api and HttpSession object

I am learning Spring security and Spring MVC, but I realized I needed to learn jsp Servlets first and general web programming in a java environment.
I have confusions surrounding the HttpServletRequest and HttpServletResponse objects and how they can be used to add headers to the request and response objects and how they relate to sessions.
As far as I understand, a cookie is a type of header just like Content-type and Accept.
The java servlet api just makes it easy to work with the header by using methods specific to the context in which the header is being used. For example:
response.setContentType(String mimeType)
response.setContentLength(int lengthInBytes)
My confusion starts here.. Cookie is not a String or int, its a object:
response.addCookie(Cookie cookie)
response.getCookies()
Since a cookie is a type of header, can't I just use something like this:
String cookieVal = response.getHeader("cookie")
I'm having difficulty understanding session management and how it relates to the HttpServletRequest and HttpServletResponse API.. What is the HttpSession object for?
HttpSession.getAttribute() // What is this getting??
HttpSession.setAttribute("Bla Bla", "valuetoset") // What is this setting?
You can read the RFC describing Cookies and the related headers, Set-Cookie and Cookie to understand what they are.
You can go through Chapter 7 of the Servlet Specification if you want to understand in detail how Cookies and Sessions are related.
You first need to understand that HTTP is a stateless protocol. This means that each request that a client makes has no relation to any previous or future requests. However, as users, we very much want some state when interacting with a web application. A bank application, for example, only wants you to be able to see and manage your transactions. A music streaming website might want to recommend some good beats based on what you've already heard.
To achieve this, the Cookie and Session concepts were introduced. Cookies are key-value pairs, but with a specific format (see the links). Sessions are server-side entities that store information (in memory or persisted) that spans multiple requests/responses between the server and the client.
The Servlet HTTP session uses a cookie with the name JSESSIONID and a value that identifies the session.
The Servlet container keeps a map (YMMV) of HttpSession objects and these identifiers. When a client first makes a request, the server creates an HttpSession object with a unique identifier and stores it in its map. It then adds a Set-Cookie header in the response. It sets the cookie's name to JSESSIONID and its value to the identifier it just created.
This is the most basic Cookie that a server uses. You can set any number of them with any information you wish. The Servlet API makes that a little simpler for you with the HttpServletResponse#addCookie(Cookie) method but you could do it yourself with the HttpServletResponse#addHeader(String, String) method.
The client receives these cookies and can store them somewhere, typically in a text file. When sending a new request to the server, it can use that cookie in the request's Cookie header to notify the server that it might have done a previous request.
When the Servlet container receives the request, it extracts the Cookie header value and tries to retrieve an HttpSession object from its map by using the key in the JSESSIONID cookie. This HttpSession object is then attached to the HttpServletRequest object that the Servlet container creates and passes to your Servlet. You can use the setAttribute(String, Object) and getAttribute(String) methods to manage state.
You are correct that cookies are managed using headers. There are TWO cookie management related headers: Cookie and Set-Cookie.
Cookie header is sent by the user agent (browser) and will be available in your HttpServletRequest object and the Set-Cookie header is appended to your HttpServletResponse object when you use methods such as addCookie(Cookie).
In Java an HttpSession is established when the first request reaches your application. The Servlet Spec implementation in your container (Jetty, Tomcat, WebSphere, etc) will create and manage the HttpSession. The browser will receive a JSESSIONID cookie which will identify this particular session in the future.
Agreeing with the answers given above, I would like to conclude that Cookie and Session are two different entities in the world of web.
Cookie
Cookie represents some brief information that's generated by server and stored on client(browser). According to HTTP mechanism, browser have to send all the cookies(that have not expired), that server had sent before to browser.
Session
HTTP is a stateless protocol. Unlike FTP and other protocol, where connection state is preserved between multiple request-response transaction, in HTTP connection is established for one request and it's closed when response for that request is satisfied. This flaw in HTTP is present, because it was designed in early days to serve static web pages only. But as web has expanded, it's now used to serve dynamic full-fledged webapps. Thus, it has become necessary to identify users. Thus, for every request served by web-server, a labeling mechanism is required which can identify user of each request. This identification of user of request(whether the request has came from same user, same machine), sessions are used.
Session can be successfully implemented only if web-server can receive any information about the user in the request. One way of making this information available to user is Cookie. Others are URL rewriting, hidden fields, etc.
session.setAttribute() will store information in current session on server side not on client side(browser).
Hope it may help you.
Ok Looks like you want to see the difference between Cookies and Headers. They have different purpose. Cookies are temporary storage of information on client side. Server set the cookies(data) on the response and once set browser send these cookies(data) with each subsequent requests till the cookie expires. But headers are used as hints to browser and server. For ex
setHeader("Content-Type", "application/json");
will inform client to prepare to see a json response in the payload. Since it is a "one time" information there is not need the browser to send that information back to the server with each new requests like cookies.

How do I create a new HttpSession in a RESTful webapp?

I have a need to create a HttpSession (via cookie) whenever a client invokes a particular UI.
Assumptions:
Let's assuming that I'm not going to worry about any deep oAuth-like authentication dance. JESSIONSID cookie impersonation is not an issue for now.
The server is tomcat, thus a JSESSIONID cookie is sent down to the client if a new session is created.
Design issues:
I'm grappling with how to design the URI. What is actually the REST resource ? I already have /users and /users/{someuserid}. I wanted to use /auth/login but in one previous SO question, one cited article says that we should not have verbs in the url. I've noticed that even Google makes the same mistake by having https://www.google.com/accounts/OAuthGetRequestToken. So in your opinion, are /auth/login/johndoe (login) and /auth/logout/johndoe (logout) good options ?
UPDATE:
I've changed my design. I'm now thinking of using the URIs /session/johndoe (PUT for login, DELETE for logout). It should still be within the limits of the REST ethos ?
Aren't sessions irrelevant in REST Style Architecture?
http://www.prescod.net/rest/mistakes/
I am in the midst of creating a REST endpoint that recognizes sessions. I've standardized on:
POST /sessions => returns Location: http://server/api/sessions/1qazwsxcvdf
DELETE /sessions/1qazwsxcvdf => invalidates session
It is working well.

Categories

Resources