We need to enable java servlet sessions support for one Google App Engine project, but session will be used only in one servlet (small isolated part of application).
Would we get some increased latency impact (because of session memcache/datastore object) in other servlets although session object would not be used in any other servlets?
Is there a way to disable sessions support for some servlets ?
There is no way to enable sessions on a per servlet basis.
Also sessions consume a read from memcache and a write to datastore for every request. So this can get costly.
Additionally if your client does not handle cookies (usually devices via REST), then every request will create a new session entity in datastore. And this will grow indefinitely.
The solution is to roll your own sessions - create servlet filter that gets/sets cookies only for certain path/servlet.
Related
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.
What's the scenario of share session on server side? And is there some approach to share the session on server side in JAVA EE platform?
As the problem does not explicitly say the objects between which session needs to be shared, I can suggest following options:
1) If you need to share session between different web apps on the same server (tomcat) , you can use:
<Host name="localhost" ...>
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
</Host>
2) If the server is not tomcat, please refer to SSO option for the respective server.
3) You can as well use a full fledged SSO product like CAS (http://www.jasig.org/cas) which will allow you to share sessions across apps across different servers but not between users.
4) If you need to share session between different users, all you need to do is pass on the session ids between different clients (typically browsers) based upon your share criteria like, people playing same game, accessing same bulletin board and can collaboratively changing the data. However, please understand most of the security infrastructure is built around mapping of session ids. If you choose to make the session ids explicitly accessible between multiple users, you would have to re-create lots of security filters yourself.
5) Alternatively, best approach will be to manage the state of the object differently from session. The state of the shared object can be shared across multiple sessions in much more standards compliant secure and auditable way.
On Java EE you must review the Servlet Specification, the object HttpSession provides the behavior for manage the session on the server side.
http://docs.oracle.com/javaee/5/tutorial/doc/bnagm.html
Although you can store any object in the session, this practice can be dangerous because the objects remain on session until it expires or the object is removed, so if your program doesn't manage well the objects that are stored in the session you can consume to many heap memory.
The objects of session are deleted when it expires, the expiration time is configured in the deployment descriptor web.xml or can be set by client. If you don't specify a time for session expiration then the default is 30 minutes, this 30 minutes are counted from the last request made by the user.
My recommendation is that you don't store objects in session, you must use the object HttpServletRequest and the mehtos setAttribute and getAttribute for pass objects between requests. I you need store a value on session you can store the ID of a product instead the whole product. A common use of the session is for store variables that must live for more than a request and you don't want to store it on cockles for security reasons.
thank you you guys for looking at my post.
Due to grey areas in licensing issues, I have two instances of tomcat running. I'm using Apache proxy to seamlessly communicate between the two.
App1 lives in tomcatA.
App2 lives in tomcatB.
Both requires user authentication and uses sessions for storing data. App1 is the only one visible to outside world and all the requests that comes in to App2 are generated by JavaScripts from App1. Unfortunately, App1 has a session and sends that specific JSESSIONID to all the requests from App2. Since there isn't a session with that specific id in App2, it returns with errors.
Is there a way for me to initialize a session with specific id?
Is there a way for me to modify all the requests so that it puts the valid session id into the headers.
Edit: I need App2 to realize that requests coming through, from App1, with a particular session id maps to a session that App2 created.
Even if both application lived in the same Tomcat, sessions would be different as they are issued on a per-app basis. Personally, I am not entirely convinced by this design.
If your question is how to propagate authentication to another app, use a single sign-on application like Josso or a CAS; to share session data, you can use a centralized cache accessible from both applications and accessible through JSON.
And yes, session data is bad.
Update: can't you simply implement a handshake protocol like: app2/register/{app1 session id} - at this point you both hold both session ID's and you can correlate each other. This can be done also with a session listener.
You could just use a different session cookie name (or path, if possible) for your tomcatB. tomcatB would thus consider the JSESSIONID cookie as any other cookie, and not as a session cookie.
See http://tomcat.apache.org/tomcat-7.0-doc/config/context.html.
I do not know how to use Session on Google app engine.
Please tell me.
Thanks.
Are you talking about request.getSession() in the Java Servlet API? You have to enable sessions before that will work. See this question for more info on using HttpSession. By the way, you should probably tag your questions with the App Engine variant you're using (java or python).
App Engine includes an implementation of sessions, using the servlet session interface. The implementation stores session data in the App Engine datastore for persistence, and also uses memcache for speed. As with most other servlet containers, the session attributes that are set with session.setAttribute() during the request are persisted at the end of the request.
This feature is off by default. To turn it on, add the following to appengine-web.xml:
<sessions-enabled>true</sessions-enabled>
I want to run my tomcat-instances in a configuration where requests are served to several tomcat-instance via round robin. I don't want to use any internal cluster manager.
As far as I see if every request is served by different tomcats, an unknown sessionId would arrive at a tomcat, so it would be forced to create an new session and overwrite the old sessionId. So for every request a new session would be created. This seems to be a lot of overhead.
Is my view on that things right? Is there a way to disable tomcats sessions management?
Regards,
Michael
Basically you have two choices:
1) Replicate your sessions so they become reachable by any Tomcat node. Solutions: Tomcat Cluster, memcached-session-manager, possibly others.
2) Use a load balancer and implement sticky sessions. First requests will be routed randomly on a round robin basis, but subsequent requests will stick to the same server. Solutions: mod_proxy, hardware traffic managers.
The disadvantage of the first option is that session replication is costly, not very reliable and often requires Serializable-only data to be put in session.
The disadvantage of the second approach is that if you shut down your Tomcat for maintenance, the users will be forced to log in again.
You are incorrectly assuming that "for every request a new session would be created". The new session will be created only if not created before on that same server, or if it was created but already expired.
We usually used Tomcat behind an Apache web server with mod_jk for load balancing the requests across the Tomcat instances.
With sticky sessions a user will only get a session upon the first request and will afterwards always be directed to the Tomcat from where his session originates. So there is no need to replicate sessions across all Tomcats and the requests will be distributed across the Tomcats, too.
Of course, this does not ensure some kind of round-robin which you asked for.
A session will only be created once your code requests the session so if your application doesn't require the session then just simply dont access it. Checkout the section on getSession() in HttpServletRequest
http://download.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html#getSession(boolean)
I'm not sure if there is a way to replicate the session across different tomcat instances however if you require some user state without session then you can use cookies instead.
EDIT: If you do need to replicate the session you could probably start by reading this tomcat document.
http://tomcat.apache.org/tomcat-5.5-doc/cluster-howto.html