This is just the continuation of this post.
I'm coming from ASP.NET world. In ASP.NET I had a few options to store the session: "In proc" and "Out Proc" which mean the session will be serialized and stored either in database or in Session management service. This practice is also relevant to load balancing if I don't want to have my session sticky.
what is the Java/tomcat alternate solution for such cases?
How can I store out of proc session?
What is the load balancer solution?
Thank you in advance.
There is no built-in "out proc" session type for J2EE (at least, not one that is known to me). If you need to store "session" type data, but can not use the HttpSession to do so, then you will have to roll your own solution. This is likely to involve the following:
A session identifier that is stored on the client. You will want to use an identifier that is not easily spoofed if your application faces the Internet (versus an internal only app).
An API (maybe just a few classes) on the server side to retreive the session information from somewhere (perhaps a central database).
https://wiki.jasig.org/display/CAS4UM/JPA+Session+Storage
Related
I'me reading Marting Fowler's famous book Patterns of enterprise application architecture to systematize my knowledge.
I've read chapter Session and States and I a bit confused. In the first part of the chapter author recommend to use stateless server to avoid some sort of issues. Then author says that sometimes wee need to save some data on the server side - for example user cart in a internet shop. But to implement session with state we can use stateless server. Then author describes ways to save session state(client, server, database)
But after reading this chapter I don't understand what a stateless server is. How a server can be stateless if it keeps session state ?
Quora has a nice definition:
A stateless service is a service that does not store any data on the application server. It reads or writes data to the database, returns a value (or not), and after that, any information on the task itself is forgotten.
Meaning: it isn't that server itself that keeps the state data. It can put it into some database. It might then provide the client with some sort of token that the client can include in future calls. And that token enables other servers to retrieve the corresponding data from say, a database.
The key point is: sure, the information needs to be stored somewhere. But that somewhere isn't the server, but some infrastructure that all the stateless servers can get to.
I want to use a cookie based HttpSession in a serlvet container. All session data should be stored inside the cookie. It seems to be uncommon within servlet applications. In Rails (Session) and Playframework (Session), this kind of session handling is the default. Why is this so uncommon?
In concrete I need a solution for JBoss EAP6 (without session scoped beans). I found two implementations based on serlvet filters:
Stateless Servlet Filter "This filter is still in a beta status." 2013
java-stateless-http-session No references for usage and no commit for more than a year. No tests.
Do you know any alternatives?
(If possible I don't want want to discuss pros and cons in general)
It is uncommon in Java EE to have session data persisted in cookie ... because HttpSession is implemented in all servlet containers.
In cookie persistent sessions, you have a limit in size, and you must use signed data to avoid manipulation of session client side. You must crypt data if you want to keep sensitive informations in session. And all session data is exchanged with every request and response. Those limits go away with HttpSession.
The highest interest of cookie persistent sessions is that you can have a farm of multiple servers that can respond to any request, because the session is contained in the request. But this can be done in Java EE by using sticky sessions at a reverse proxy level (because you have reverse proxies in almost every serious data center) : the reverse proxies know about the session and pass a request to the server that holds it.
Some Java EE servers have even a notion of shared sessions.
IMHO it is not that is would be very hard to implement a cookie persistent session in Java, it is simply that for professional usages, it has not been found as important enough.
In my web appication i need to recognize signed in users even if they restart the browser ("Remember me" function of web sites). What is the best practice to achieve this using Java Servlet API?
I've considered the following options:
Using long-term HttpSession sessions and storing user identifier as an attribute of the session. This approach doesn't permit user to restart browser, because JSESSIONID cookie is not persistent and there is no standard way to change its properties. The only option i consider is to use SessionCookieConfig interface of Tomcat 7.0 to tune default JSESSIONID parameters. But there are doubts about the scalability of such solution, because Tomcat will store all sessions for a long period of time.
Using short-term HttpSessions together with some persistent cookie which stores the user identifier with some security hash. When user restarts the browser, it sends persistent cookie and application server binds new session with user identifier.
What is the common way to achieve this?
I have always needed more control over my sessions, because I need them to work across multiple web applications, so I implemented my own solution from scratch. It is pretty easy, just hash a random number and store it in a database. If you don't have or want a RDBMS just some sort of key/value store.
Are you using normal filter-based authentication? How secure does your site need to be?
One way:
Drop a cookie with a code in it on their browser. In Tomcat, have a typical filter configured. The filter grabs the code and checks it against the database for validity. If the code is valid the normal Tomcat authentication is avoided. If there needs to be any persisted session variables, you can load them from the database now.
Drop a new cookie code with every response. It should include a hash of a salt, the user's ID, and the user's IP address. That way the cookie will do no good if the request comes from the wrong computer. Though IPs are spoofable.
Bear in mind, you're short-circuiting security when you do this. You're saying, "Oh look, you've just come out of nowhere. I think I know you! Here, have the keys to my castle!" This sounds like the sort of request we'd get from the marketing folks who didn't understand a thing about security and didn't care since it wasn't there problem if we got hacked.
Hey, I am in a WTF code situation working on a jsp tomcat server and trying to pass session data (user id, etc.) to php. i am planning to rewrite php session handling with session_set_save_handler()
my question is where does tomcat stores it session data (harddrive?) and what kind of encoding does it uses?
or am i on the wrong path?
i know the idea of mashing php and jsp is stupid just got this assignment and i am pissed too.
Try to avoid sessions between different systems. You can't really share sessions between PHP and Java because,
They run under different processes, maybe different machines. There is no shared memory.
Their session data structures are totally different.
The serialization is not compatible.
Different cookie flavors, "PHPSESSID" vs. "JSESSIONID".
You pretty much have to do session management yourself to share sessions. It's pretty complicated. Following are the components you have to write,
Setup a common session store, like a DB or memcached. The session is stored as big blob.
Design a common session data structures. I just use name-values pairs. The same name must be used on both systems and the values must be string (UTF-8).
Use a common serialization. I would go with PHP's session_encode(), which is fairly easy to handle on Java.
Handle your own session cookie.
You could try using database driven sessions to solve this issue. Assuming that tomcat and apache have the same session hashes, it may be possible to transfer them across servers? You need to look in the tomcat config file and it SHOULD be under something prefixed with session. That is where I would start. Typically, on an Ubuntu linux server it would be under something like /etc/apache2/apache2.conf.
I hope this helps and good luck!
Kyle
I believe the default session manager for Tomcat will store session data in a SESSIONS.ser files in the "work" directory for your application.
You may want to create and configure your own session manager: http://tomcat.apache.org/tomcat-5.5-doc/config/manager.html
I want the clients of several related web apps to hold their own authentication state. This improves scalability, because no session replication between cluster nodes is needed. And it makes integration of different server technologies like Java Servlets and PHP easier.
My plan is as follows:
Set a signed and encrypted cookie with the user name and session expiration time after client authentication.
When the client sends a request, the server decrypts and validates the cookie and grants or denies access depending on the cookie values.
The session expiration will be updated through resetting the cookie.
All servers that want to use the session have only to know the cookie mechanism and the decryption key. See also: Session state in the client tier
Is this approach ok? Would it be possible to integrate it into a servlet container / application Server so that it is transparent to the applications? A servlet should be able to use HttpServletRequest#getRemoteUser() for example. Is this possible? Or would I need something above the container level like Spring Security? Are there any existing libraries for client side session management?
Not a good idea. Storing vital data like session expiry and user name entirely on client side is too dangerous IMO, encrypted or not. Even if the concept is technically safe in itself (I can't answer that in depth, I'm no encryption expert), a break-in could be facilitated without compromising your server, just by acquiring your encryption key.
Somebody who gets hold of the key could generate session cookies at will, impersonating any user for any length of time, something the classical session concept is designed to prevent.
There are better and scalable solutions for this problem. Why not, for instance, set up a central session verification instance that all associated servers and services can poll? Look around on the web, I am 100% sure there are ready-made solutions addressing your needs.
I disagree with the posters saying this approach is not secure. Variants of it are used in a number of well respected frameworks, such as Rails and Play!, for precisely the reasons you outline, and it's perfectly secure when implemented correctly.
This improves scalability, because no session replication between cluster nodes is needed.
First, using HTTP Session doesn't really prevent you from scaling, even when using HTTP Session State replication (some mechanisms are smarter than others by the way, for example WebLogic's in-memory replication doesn't have a big overhead). Second, do you really need it? Most applications (the majority) don't need Session replication. Third, am I understanding right: do you plan to not use HTTP Session at all?
(...) Set a signed and encrypted cookie with the user name and session expiration time after client authentication.
Don't do this! Don't store a username and other sensible data used by the server in a cookie, this is a very bad idea! You actually need to admit that it's just a matter of time before someone figures out how your system works and breaks it (especially if your cookie is candidate for crib attacks). Sor, really, you should store data in the Session on the server-side and only an ID in the cookie, like things are actually working. This is much more secure.
Is this approach ok?
No. And you don't need this for interoperable single-sign on (if this is what you are trying to build). Just use a centralized authentication solution like CASJasig which has libraries for various technologies.
This is not really how Sessions are implemented. The cookie itself doesn't need to carry any data of the session itself, it's just a reference to it.
What the Cookie holds is usually a Session ID which is then linked to the data on the server.
If you don't have a central data session server for the other servers to access, I suggest to get one :).
You can avoid duplication of data in a clustered environment by using a state server - a server that is well known by all the nodes in the clusters and maintains the session data for all the users. Every time a user performs a request, it send a cookie with session id to the applications server; this one should retrieve the session from the state server. This is possible for asp.net development, but I'm not sure how easy Java supports this approach.
As Pekka said, not a good idea. One can intercept your cookie with sensitive session data. Even with SSL, by using fiddler2 one can decrypt the traffic