I am using Spring-MVC to build a website prototype. We have a MySQL database that we address using Hibernate.
Now, I want to add basic user session handling (user can login, do stuff on the site and logout). I thought it should be easy to do, but after a bit of research I feel a bit lost.
I have seen the spring-session project. It seems it depends on a redis server for storing session data. Is there a way I could use my existing Mysql/Hibernate setup for storing the session data?
Also, what is the most easiest way to do sesions in spring-mvc ?
Sessions will be maintained within the web/app servers like Tomcat, Weblogic etc., you need not to store session related stuff in any database.
Related
I've worked with Java EE (now Jakarta EE) since before it was named "EE" (i.e. servlets, etc.) but the last time I was deeply into session management was over 15 years ago. Now we have new technologies and trends such as the HTML5 Web Storage API and JSON Web Token (JWT). While one can debate the benefits of JWT for session tracking, there are some interesting benefits to keeping track of a session in a single tab using the sessionStorage.
So just to bring me up to speed:
Are the latest Java EE technologies (Java EE 8) still restricted to cookies and URL rewriting for session tracking, and
Do the most recent Java EE APIs allow me to provide custom state management, e.g. override how the container finds state (if I wanted to store a state identifier in sessionStorage instead of a cookie, for example)?
All the discussion I've seen seems to dance around this question. If someone could direct me to some existing documentation, if there is any, that would help, too. Thanks.
localStorage is for keeping data for the use in the browser across sessions. For session data, one would use sessionStorage. None of the data stored there ever goes to the server without being explicitly posted.
Session data could also be stored on the server side by the container. The state can be identified in any of the standard ways of an HTTP header or a cookie. The developer may use a home grown implementation to hold the session identifier. If Spring Session is used for session management, then the eager developer would need to implement a custom session ID resolver.
I've a large application working on and I am facing with hte problem of sessions a lot, it just unset or corrupt the session of my application sometime, all I got it undefined in my session.
By the way I need to know is there any alternative of sessions so I came to know after R&D that I may use cookie, but I think these things are same before .
So I am stuck, don't know how to get rid of my problem.
Now I've some questions as I am a beginner
what is the difference b/w sessions and cookie in sailsjs.
how to set and get cookie in sailsjs.
i am using sails version v0.94
Please guide me in this.
Session is a schemaless object that can be saved in memory or a persistent store such as Mongo or Redis. Using a memory store like Redis or Mongo helps to persist your sessions across multiple application servers or during an application restart.
The cookie tracks a user with a specific ID to associate with the session. Sailsjs, on top of Express, manages cookies and sessions automatically. When a user accesses your site it is assigned this cookie that has a unique ID. Then sails/express automatically will associate session information to that particular client based on their unique cookie. Sails does more than express by allowing you to use this with with sockets as well.
This is all done so you don't have to save and update session the same as a normal DB. You just set the property and move on.
The reason not use cookies is if you prefer to keep the information on the client and do not want to create overhead for your server to look for that value in memory or in a DB. You will want to make sure this information does not need to be secure.
To learn how to use cookies you should google "Expressjs Cookies" (remember sails runs on top of express, current version 3.x)
If you want an alternative to sessions / cookies you can look at web tokens http://jwt.io/
Remember sailsjs runs on expressjs if you can't find what your looking for, then always search for an express solution as well.
Are there any benefits to ColdFusion sessions vs J2EE sessions?
The ColdFusion session documentation mentions the benefits of J2EE sessions, but not any advantages of ColdFusion sessions. J2EE sessions have been available since ColdFusion MX (released in 2002), but there are still a lot of people using standard ColdFusion sessions. Are there any disadvantages of J2EE sessions that aren't present with ColdFusion sessions?
J2EE session management provides the following advantages over ColdFusion session management:
J2EE session management uses a session-specific session identifier, jsessionid, which is created afresh at the start of each session.
You can share session variables between ColdFusion pages and JSP pages or Java servlets that you call from the ColdFusion pages.
The Session scope is serializable (convertible into a sequence of bytes that can later be fully restored into the original object). With ColdFusion session management, the Session scope is not serializable. Only serializable scopes can be shared across servers.
Therefore, consider using J2EE session management in any of the following cases:
You want to maximize session security, particularly if you also use client variables
You want to share session variables between ColdFusion pages and JSP pages or servlets in a single application.
You want to be able to manually terminate a session while maintaining the client identification cookie for use by the Client scope.
You want to support clustered sessions; for example, to support session failover among servers.
There are no serious disadvantages to using Java EE session cookies, and there are some advantages to using them, as indicated above in your question.
The one disadvantage to Java EE tokens is that the cookies cannot be easily modified programmatically. CF Tokens can. You can modify CF Tokens to be session only. You can also modify them to be SSL-only and httpOnly.
You can make Java EE tokens SSL-only and httpOnly as well, but it involves JVM arguments.
In CF9, Adobe also improved the randomness of CF Tokens to be more on par with Java EE tokens.
I really don't think it matters which one you use (assuming you're on CF9 or higher). But Java EE Tokens are the closest to working securely out-of-the-box. But if you want to go beyond just setting the cookies to "session-only" and have them be SSL-only and httpOnly, you'll need to dig into the JVM settings. You cannot do that in your App.cfc.
CF native sessions don't use Session cookies, so can last across browser/machine restarts, whereas all Java EE servers by default use session cookies,so your session can only last as long as your browser is open.
I can't find where this behaviour is specified in the Servlet JSR, but in Servlet Spec 3.0 (i.e. not JRun) , you can set an expiry date for your Java EE session cookie in order to mimic the CF native session behaviour.
As nosilleg mentions, this is could be a bonus, but also could be seen as a security problem, depending on the security requirements of the app your're working on.
One of the main disadvantages of J2EE session variables in ColdFusion is that changes such as making them "secure" cookies takes place instance wide.
This means that every site that is running on that instance must run under https, including ColdFusion administrator itself. For servers that host multiple sites that require sessions, this will generally be problematic. Additionally, if you're running the ColdFusion Administrator from the built in web server, there's a bit of a process to get that working under ssl.
If you need the documented advantages of J2EE cookies, and need the cookie to be secure then all sites that requires sessions must be on https.
If you don't need any of the documented advantages of J2EE cookies, and you're running CF9 or later, then you're better off going with ColdFusion cookies.
Note that Railo still has the same issue but with more flexibility since the cfapplication tag has a sessiontype attribute where you can choose between j2ee or cf session cookies on a per site basis.
I had one tiny problem where I completely lost session variables between requests. I was using a cfhttp post with J2EE sessions. Imagine this scenario:
1. call.cfm in wwwRoot/test folder makes a call to an index page also in the same folder.
2. index.cfm sends the request to wwwRoot/test/controller/login.cfm.
3. login.cfm sets some session variables and sends the user to wwwRoot/test/index.cfm
4. index.cfm does not see the session variables created.
All the send requests are done via cflocation with addtoken="yes".
Turn off the J2EE session variables, and viola! It works just like the way it should.
cflocation and session variables
I'm faced with a curious problem in my current project:
I've got multiple Spring MVC based web apps deployed on a Glassfish 3.1 server - and I need to be able to "timeout" the user based on the "sesion timeout" parameter in their respective web.xml - no matter in which application the user is on. Please don't ask why the applications are in separate WARs - the architecture is so. The user is logged in via WebApp A and is redirected to a WebApp B - and then the user can keep jumping to different web apps - I guess you get the idea. The WebAppB etc. have numerous Ajax calls (I'm not even going there) as well. The question, I guess, boils down to the fact that I'm not able to share session data between WebApp A and WebApp B (I may be wrong here - and this is where I require help) and so I don't have any way to know by checking
httpServletRequest.getSession(false)
in WebAppB since it returns null in both cases when the first request hits the WebAppB and the first request "after" a session timeout. I have to keep "something" in the WebAppA's session and check for its existence in WebAppB's session - which brings me back to the issue of sharing session data within web applications. I cannot use DB storage, since that would mean a DB call on every request. I got a direction by googling that "crossContext" thing in Tomcat helps in such scenarios - but will something like this be helpful in Glassfish ( there's a "crossContextAllowed" property for sun-web-app.xml which I recently found).
I've been stuck with this for quite some time now and I'm not even sure this is a question worth your time - so thanks in advance for trying to help.
Trishul
I cannot help you with the Glassfish implementation, but what you need is a form of Single Sign On between webapps.
To implement this form of SSO you usually need to do two things:
Make sure all your webapps share a common root context i.e webapp A is on /commonroot/webappA and webapp B is on /commonroot/webappB. The reason for this is that the same session Id must be delivered to the two webapps when the user switches between them. Session Ids are usually stored in cookies and browsers deliver cookies based on path. There must be a setting on Glassfish (as there is on Tomcat and Jetty) which can "force" webapp A to deliver a cookies on path "/commonroot" (rather than /commonroot/webappA) and webappB to do the same. Any access to webapp A or webapp B will then pull and provide the unique session id from the cookie associated with the /commonRoot path.
Once you have all your webapps within the same 'SSO context' share a common session for an user, you need to have these webapps access the session from a common, unique store. A DB is a usual way to do it but if you are looking for speed, something like memcached or hazelcast may be more appropriate. The advantage of using a DB is that it additionally provides session persistence: if your session store is bounced, an user making a call with a session which is not expired will be transparently reconnected without having to login again.
Servlet/JavaEE containers usually provide samples of SSO Realms/SessionManagers or equivalent that will directly implement what you require or that you can hack to fine tune to your needs.
Is there anyway to user MongoDB as a central session storage for Tomcat6? If so, could we have a cluster of tomcat servers reading session data from MongoDB so that the cluster could be dinamically resized (adding more boxes on the fly) without the need of sticky sessions?
I think I found what I was looking for.
https://github.com/dawsonsystems/Mongo-Tomcat-Sessions
If anyone has used it in production, I would love to hear your experiences.
Tomcat/J2EE sessions have a getId() method which returns the session ID for the current user. You can certainly use this as a key into a sessions collection in MongoDB, and store any data you'd like.
I'm not aware of any pre-built tools to integrate specifically with Tomcat 6, but that doesn't mean they don't exist. But this is a fairly straightforward task, it might be simplest just to write your own DAO to access session data given an HttpSession or HttpServletRequest.
If your session data is the only shared state you maintain, then moving it to MongoDB (or to any off-appserver database or tool) will enable you to scale like you propose. If you have other state maintained on the application servers, then you will need to determine how to move that off of the app servers and onto a shared resource.
I think there is a better way using MongoDD to store sessions, just using Servlet-Api functions and no proprietary Appserver-features.
First of all you need to create your own implementation of an
HttpSession based on a Map for storeing attributes
You need to create an implementation of HttpServletRequest (using HttpServletRequest Wrapper) that overwrites getSession-method and
returns your implementation
You need to create a filter which replaces the given HttpRequest against your created and do the MongoDB-Handling to load and store the attribute-map
You find some code-samples (sadly in german language) here: http://mibutec.wordpress.com/2013/09/23/eigenes-session-handling-in-webapplikationen/