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
Related
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
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.
I am designing an enterprise security server for our company - we own many different applications, most written in java and a few written in PHP. I could provide a remote API that would give each application access to the server. I could also create 'agents' that each application could include that would do all the work for them, but allow my server control over their sessions and thus their authentications/authorizations. Issue is I would probably be better to write the agent in java because 80% or more of our apps are in java.
If I wrote the agent in java does anyone know if there was a way this program could access the php session? If not does anyone have a suggestion regarding a better way to go about doing this?
The session data is stored as a (php) serialized array in a temporary folder. The locations for these are set in the php.ini file.
But you can change both the format of the data and the place it is stored (e.g. to a database or shared memory or somewhere else) by writing your own handler.
A quick google suggests that several people have written [de]serializers in Java for PHP data. e.g. http://hurring.com/scott/code/java/serialize/
If you have problems with the built-in PHP serialize function - have a google for WDDX (which IIRC comes as standard) and serializes data into XML.
You might want to think about how you keep the session data appearing to be active to PHP if you want the agent to continue independently of the web session.
C.
You can hook into PHP's session handling using session_set_save_handler() (an example for a simple but complete custom handler is included in the manual). You should be able to synchronize PHP's session management with a central Java server that way.
Your PHP application would receive a session ID through a cookie ($_COOKIE["SESSION_ID"] or whatever).
Your custom session_save_handler would, instead of maintaining a session store of its own, pass that session ID to your central Java-based security server, and get all the session data in return. Writing into a session from PHP would be routed the same way.
You could of course also go the other way, and poll PHP's internal session data from the outside, but wouldn't quite understand what exactly for. If that is the case, can you go into more detail there?
Preface: I'm not a java developer.
I have a question about Tomcat / jBOSS and other java application servers. Where are sessions (session data) stored? In PHP, sessions are usually stored in the database which means you can easily share session data in a load balanced environment. In Tomcat and other application servers, session seem to be stored in memory by default which would not apply in a load balanced env. While it is true that PHP stores sessions in files by default, it takes a few lines to hook it up to a DB. Is the same true of applications servers?
Basically, what's the pros for storying sessions in memory? Is this still standard practice for application servers? Thanks all!
I have a question about Tomcat / jBOSS and other java application servers. Where are sessions (session data) stored?
By default, I'd say in memory. Details are actually... implementation details which are application server specific.
In PHP, sessions are usually stored in the database which means you can easily share session data in a load balanced environment. In Tomcat and other application servers, session seem to be stored in memory by default which would not apply in a load balanced env.
Well, not exactly. What this means is that a client request has to be sent to the same node in a clustered environment (this is referred to as "session stickiness") and this is not an issue from a load balancing point of view. But this is an issue from a failover point of view: in case of failure of a node in a cluster, session state managed by the node can be lost. To solve this, almost all application server providers implement session failover (using various mechanism such as in-memory replication, JDBC-based persistence, etc). But, again, implementation details are application server specific. See for example how Tomcat or WebLogic deal with that. The Under the Hood of J2EE Clustering article on The Server Side is a very interesting reading too.
While it is true that PHP stores sessions in files by default, it takes a few lines to hook it up to a DB. Is the same true of applications servers?
As I said, not all application servers will offer JDBC-based persistence. Having that said, and to answer your question, configuration is in general simple when they do. But using a database is really not the preferred solution (actually, I avoid it at all price).
Basically, what's the pros for storying sessions in memory? Is this still standard practice for application servers?
Simply: performance! Serializing data, calling a database, writing to disk, all this has a cost. In-memory replication obviously allows to avoid some overhead. But it has some limitation too. For example, it doesn't allow WAN HTTP Session State Replication with WebLogic. But well, only few people need this :)
With the provided Session Manager, the session is always in memory but it has a manager to persist the session to JDBC store,
http://tomcat.apache.org/tomcat-5.5-doc/config/manager.html
Unlike in PHP, the session is still accessed from memory and it's only persisted to DB when the memory limit is reached or at server shutdown. So your load-balancer must have sticky routing for this to work.
The benefit of in-memory session is performance because db access doesn't occur for every transaction.
You can write your own session manager to simulate the PHP behavior.
The JavaEE spec does not dictate this, it is up to the individual implementations to decide. For example, the usual way to handle load balancing in Tomcat is to use replicated sessions, where the session data is multicast between the nodes. Storing session data in the database is a huge performance killer, and while Tomcat may support it, I really wouldn't recommend it.
Tomcat (version 5 here) stores session information in memory. When clustering this information is periodically broadcast to other servers in the cluster to keep things in sync. You can use a database store to make sessions persistant but this information is only written periodically as well and is only really used for failure-recovery rather than actually replacing the in-memory sessions.
If you don't want to use sticky sessions (our configuration doesn't allow it unfortunately) this raises the problem of the sessions getting out of sync.
In other languages, web frameworks tend to allow you to use a database as the primary session store. Whilst this introduces a potential scaling issue it does make session management very straightforward. I'm wondering if there's a way to get tomcat to use a database for sessions in this way (technically this would also remove the need for any clustering configuration in the tomcat server.xml).
There definitely is a way. Though I'd strongly vote for sticky sessions - saves so much load for your servers/database (unless something fails)...
http://tomcat.apache.org/tomcat-5.5-doc/config/manager.html has information about SessionManager configuration and setup for Tomcat. Depending on your exact requirements you might have to implement your own session manager, but this starting point should provide some help.
Take a look at Terracotta, I think it can address your scaling issues without a major application redesign.
I've always been a fan of the Rails sessions technique: store the sessions (zipped+encrypted+signed) in the user's cookie. That way you can do load balancing to your hearts content, and not have to worry about sticky sessions, or hitting the database for your session data, etc. I'm just not sure you could implement that easily in a java app without some sort of rewriting of your session-access code. Anyway just a thought.
Another alternative would be the memcached-session-manager, a memcached based session failover and session replication solution for tomcat 6.x / 7.x. It supports both sticky sessions and non-sticky sessions.
I created this project to get the best of performance and reliability and to be able to scale out by just adding more tomcat and memcached nodes.