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.
Related
I have web client which invokes multiple services. As soon as the user is authenticated, I want to store the email Id somewhere as it sends the email Id for each request.
I don't want to use session as I have heard that is the best practice. In REST, all data must be sent for the request and it must be stateless. What other alternatives are there? Is using DB for session management still not breaking the stateless principle of REST?
I went through If REST applications are supposed to be stateless, how do you manage sessions? but there were many contradicting opinions there. Should the email Id be stored in session storage of the browser then?
I think you should do it with a authentication header. Check out these threads:
Do sessions really violate RESTfulness?
If REST applications are supposed to be stateless, how do you manage sessions?
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.
I am working on Spring MVC application. Usually face a problem that when server get down the client session get expired.
So, I want to make session alive. When server goes up then client not need to login again.
Can we save cookie id or session id in database to make client reconnect.
could it be what you are looking for?
how-can-i-make-the-spring-security-stores-the-http-session-in-database-so-i-can
here is the link to the blog-article:
Tomcat 7 JDBC Session Persistence
If you are using spring security, you can have your own implementation of SecurityContextRepository (By default this is HttpSessionSecurityContextRepository) to persist the session content in database. In this way when user presents his cookie the security framework filter (SecurityContextPersistentFilter) will look at your database for the session. Hence, even when server is down the context is still available in database and is loaded during next user request after server restart.
If session persistence is not an option, you may have to deploy a cluster of servers with session replication strategy.
The purpose of remember me is altogether different. It's not to have session across server restarts, but for across restarts in client (browser). Even with remember-me you can not get it across server restarts, unless you use PersistentRememberMeService (to database)
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.
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