Assuming I'm rolling my own session code, what's the right way to generate a unique and secure session id cookie in java.
Should I not be rolling my own but using something that's already been standardized?
I'm using gwt and the google app-engine platform.
How do I make sessions persist across browser/server restarts?
Using Servlet Sessions in GWT
In the remote service implementation class:
String jSessionId=this.getThreadLocalRequest().getSession().getId();
In the client code:
String jSessionId=Cookies.getCookie("JSESSIONID");
Enabling_Sessions
appengine-web.xml
<sessions-enabled>true</sessions-enabled>
No, you shouldn't be rolling your own.
The session ID needs to be cryptographically random (not guessable from known sources). It's difficult to get this right yourself.
Ideally you should be relying on the underlying framework's session management features. Servlets & JSPs, Struts and Spring have this support, which you should use.
In the extremely rare case that you are writing your own framework with no underlying session management features to rely on, you could start with the java.security.SecureRandom class to begin with. Of course, don't reinvent the wheel here, for broken session management is the same as broken authentication.
Update
Given that you are using Google App Engine, you should rely on the session management features provided by the engine. It seems that it is not switched on by default.
Related
I have read that, session is against the concept of RESTfulness.
Do sessions really violate RESTfulness?
Session Management in microservices
RESTful Authentication
Since Microservices inevitably use REST, does the same apply here as well? If so, then why do we have Spring session? It even lists 'Spring Session allows providing session ids in headers to work with RESTful APIs' as one of its features.
Apart from Scaling as an advantage of micro-services, it also provides you with the flexibility to choose polyglot architecture i.e (using the right programming language, framework, database for the right job).
If you use spring sessions(which off-course provides session replication across nodes), internally it uses Redis/gemfire/hazelcast as a replicated session store, but you will have to stick to one programming language & framework for all your services i.e Java & Spring resp.(You can off course write your own implementation in other languages to read from session store, but its re-inventing the wheels) And this will take away Benefit of Polyglot Architecture.
So typically in microservices architecture, you have a token-service(and it should be able to scale individually) implementation to generate tokens(aka sessionIds) which are used for Authentication & Authorization in each service and you should try to avoid storing the session information. It will also help to avoid "Single point of Failure".
I've created my own JDBC realm (using WildFly 8.2) as described at paragraph 50.3 of the JavaEE 7 tutorial. My understanding is that JDBC realm authentication implies that user credentials are read and checked by the server, the application doesn't even know the coordinates for the auth-reserved DB.
For a "new user sign up", the only thing I can imagine is to implement a classic solution from the inside of my application: accessing auth DB, check if chosen username is already present, insert row in the table... but doesn't this violate the whole paradigm of "container managed authentication", and maybe insert security holes?
Is there some server-implemented mechanism that I ignore?
but doesn't this violates the whole paradigm of "container managed authentication", and maybe insert security holes?
Yes, more or less. The container managed security concept, where the application is totally unaware of the authentication mechanism and the identity store (location where the user data is actually stored) doesn't really take the use case into account where an application has its own user sign up/register functionality.
The idea seems to be more intended for integrating externally obtained applications (e.g. say a Sonar or JIRA instance) into an existing enterprise structure. There the users are created by an admin using a central system like LDAP, or in some situations even an admin UI of the application server.
Unfortunately many of your typical public web applications aren't of this variety. They are standalone apps (don't integrate with existing internal enterprise infrastructure) and they effectively manage their own users.
The classical concept is an ill fit there, and that's why the Java EE Security EG is currently exploring how to best address this.
You basically have three "solutions" in the mean time:
Just define your DB connection details twice, once at the server level, once at the app. It looks like you were indeed already doing this.
Use JASPIC, which is a container provided authentication API which has the option to let the application contain the auth module. It can use the exact same data source and possible JPA entity manager and such that the application is also using.
Do your security using an external security framework, e.g. DeltaSpike Security or Shiro, that's totally implemented in "user space".
From a Java EE perspective, none is really ideal. The first has the duplicate definition and indeed somewhat violates the principle, the second is by itself okay, but JASPIC is a tad low level, and the second is a rich solution but doesn't integrate well with existing Java EE security.
I would like to know if Servlet specifications provides a way to load http sessions into my web application.
The idea is simple : every time a new http client is connected, a new session is created... and I will send this session and its values into a database (for the time being this step is easy to do).
If this "master server" dies, another machine will take its IP address, so http clients will now send their requests to this new machine (lets call it "slave server").
Here I would like my slave server retrieve sessions from the old server... but I don't know which method from Servlet specifications can "add" session ! Is there a way to do it ?
PS: it's for an university project, so I cannot use already existing modules like Tomcat's mod_jk for this homemade load-balancer.
EDIT:
I think that a lot of people think I am crazy to not use already existing tools. It's an university project, and I have to make it with my bare hands in order to show to my professors the low level mecanisms that I have used. I already know it would be crazy to use what I am doing in production, when this project will be finished, it will be thrown in the trash.
For the moment, I didn't find a "standard way" to make it with the Servlet specifications, but I can maybe do it with Manager and Session from Tomcat native classes... How can I get the instances for those interfaces ?
This isn't exactly a new idea and is called session replication. There are a couple of ways to do this. The easiest ones imho are (in ascending order of preference):
Jetty's Session clustering with a database
Tomcat's Session clustering. I personally prefer the BackupManager, which makes sure that a session lives on 2 servers in a cluster at any given point in time and forwards clients accordingly. This reduces the network traffic for session replication to a bare minimum.
Session replication with a distributed cache like hazelnuts or ehcache. There are plugins for both jetty and Tomcat to do this. Since most often a cache is used anyway, this is to be the best solution for me. What I tend to do is to put 2 round robin balanced varnish servers in front of such a cluster, which serve the dual purpose role of load balancing the cluster and serving static content from in memory cache.
As for your university project, I'd turn in an embedded jetty with automatic session replication which connects to other servers via broadcast using hazelcast. Useful, not overcomplicated (iirc, you need to implement 2 relatively simple interfaces), yet powerful. Put a varnish in front of your test machines and you should be good to go.
This feature is supported by all major Java EE application server vendors out of the box, so you shouldn't implement anything by yourself. As Markus wrote it is referred as session replication or session persistence. You can take a look at WebSphere Liberty which is available for free for development. It supports it out of the box, without need to implement anything. You just need to:
install Liberty Download just the Liberty profile runtime
configure session replication Configuring session persistence for the Liberty profile
install and configure IBM Http Server for load balancing Configuring a web server plug-in for the Liberty profile
How would you do session management for a website develloped in angular that consumes two types of REST services. The first is developped in ruby and the other is developped in Java Spring. For now I manage it with a shared table in a mysql database and a session id but i don't think this is the best solution.
A example of this problem is: how does the tomcat server knows about the session used by the rails application?
Thank you,
Davy
The REST servers should not do any session management.
they only get requests and responds to them. The client–server communication is constrained by no client context being stored on the server between requests.
How you are doing your session management in your application should not be affected by what resource provider you are using.
I agree with Philipp that a REST service should be as stateless as possible however I need some state in my appliation. (authentication)
I have found an article that gives the solution for my problem in this post about
session stickiness. This comes close to my situation of application servers on different machines and with different technologies.
In short they give 3 solutions:
maintain a session through cookies en session ids
use a database or cache
don't use a round robin technique but always let the load balancer send your request to the machine that stores your session. (not when you use diffent technologies)I.
I am currently trying to implement a single sign on solution across multiple JVM based (Grails, Servlets) web applications currently all deployed in the same servlet container (currently Tomcat, but don't want to limit my solution to just Tomcat). All web applications share a common database.
I've looked at various options from using CAS or other third party libraries to creating a new web service to handle Single Sign On, but none seem to really satisfy the business. My current implementation involves creating a new jar library which has a common implementation of AuthenticationProviders, and Pre-Authentication Filters based on Spring Security.
In this approach I have multiple AuthenticationProviders (currently Active Directory, and Database) for the application to authenticate against. Upon successful authentication a row would be inserted in a session table that contains the user, an expiration time, and a token. The token would be also stored as a cookie on the user's machine and that would be used to validate they have a current session in the Pre-Authentication Filters.
Having never done this before I want to make sure I'm not creating a huge security problem, and I'd also like to know what I would need to create the token? At this point a simple GUID seems to be sufficent?
Currently we are working on Spring Security 3.0.x, and haven't upgraded to 3.1 yet.
Thanks in advance.
I ended up solving this problem by doing the following:
I created a AuthenticationSuccessHandler which would add a cookie to the user's session which had identifying information as well as the hostname to try to secure it as much as possible. (The application was running internally at most customer sites so the risks here were determined to be minimal, but be careful about cookie jacking.)
Then on each application that needed to have SSO I implemented a AbstractPreAuthenticatedProcessingFilter, and placed in before the authentication filter which would pull the cookie out and create an Authentication object. Lastly I created an AuthenticationProvider which validated the information from the cookie.
Hopefully that helps someone else in the future for this type of request.
There are extensions available for KERBEROS, OAuth and SAML available on the Spring Security Extensions website. Here is the blog entry which provides an example: SpringSource Blog
If you are using NTLM as your SSO Provider, take a look at the jespa-spring project.
Or you might want to look at the Java Open Single Sign-On Project