How to make stateless web applications? Especially with Spring MVC? - spring

The stateless web application seems promising. How to make one? Especially with Spring WebMvc? Any guidelines?
Here are a few things on my mind:
Avoid creating session
Use a centralized storage for state info and share that among web application instances.
ADD 1
I think it is not a question of whether to keep state info or not. State info is always necessary if you want to do something useful. It is actually a question where/how to keep the state info. This article is useful. It mentioned in-proc/out-of-proc session, data cache, and why not to use session.
Related:
Use Spring MVC for Stateless web application development (no response yet)
Stateless Spring MVC
How to make a java web application fully stateless
How do I make my Web Application stateless yet still do something useful?
http://brockallen.com/2012/04/07/think-twice-about-using-session-state/

Here are some contributions. I'm not familiar with Java and Spring, but I believe these guidelines are valid regardless of your technology stack.
Stay away from sessions for authentication
As you anticipated in your question, avoid using a session to authenticate users. Sessions are peremptory and it's very difficult to replicate it consistently in a distributed, scalable infrastructure.
Also, load balancers don't work well with sessions: see Problem with Session State timeing out on Load Balanced Servers.
Use a token-based authentication system
A stateless app will preferably use a token-based authentication system. Firebase is a good example. Map the immutable user ID extracted from the token to the user data persisted in whatever storing mechanism you want to use. Since this user ID won't change, you'll be fine in a distributed database.
Don't confuse stateless with 'data persistence'-less
Sometimes people think that, by mapping a user ID to user data in a database, you are making a stateful app. It's not true. Let me make it clear:
An application that persists user information in a database and has dynamic responses for authenticated users IS NOT NECESSARILY STATEFUL. Stateless means the app won't have to distribute mutable authentication sessions across multiple servers and won't change its internal state to a particular client depending on session data.
The trick of stateless is: once a user validated its token by logging in, the server don't have to distribute anything new across the database servers and it won't change its state to that client. It can extract user info from the token and carry out what's needed to answer the request. If the token expires, the client will require a new authentication, which will generate a new token, but this is isolated from the app server, since the user ID will remain the same.
Use cookies for caching while remaining stateless
If caching in cookies some frequently requested data will improve performance, that's fine, go ahead and cache. Just make sure the cookie isn't connected to any server state and your app will not break if the client loses the cookie.

Related

How to share the same session between 2 applications

I have 2 applications : the first one is written with ruby (It's redmine) and the second one is a Spring boot app and both are hosted on the same tomcat server.
How can i do that?
Sharing sessions is not allowed. By (servlet spec) definition, a session belongs to a single web application.
Reference: Servlet Spec 4.0, section 7.3:
HttpSession objects must be scoped at the application (or servlet context) level. The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in that object, must never be shared between contexts by the container.
There are ways you can probably work-around this limitation by setting-up shared caches, etc. but it will always be brittle and potentially dangerous from a security or resource-usage perspective.
User database or user data file(nosql) with use of a unique-user-auth-token, accessible by two apps (or 3, 4, 5 ...)
Global concept :
App request connection :
is exist "old auth token" in app storage ?
yes -> app send old and request new or same if not expired
no -> continue
is exist valid auth token on server ?
yes (an app is already connected) -> send validated auth token to app
no -> set new auth token and send to app, new AT is ready for other app
server store what app request connection and is connected
apps are now able to exchange datas via the server.
Sharing Web applications is, at a minimum, Bad Practice (TM): Web Applications are completely separated by design. If both applications easily could reach into each other's session: Imagine what would happen if one would overwrite values that have been set by the other, and both applications expecting different data under the same key name.
If you only need single-sign-on, there's a SingleSignOnValve available that will make sure you'll only need to sign in once (provided that you authenticate through the container, e.g. a Tomcat Realm). Check server.xml for the commented-out-default-value, or the documentation for more information on authentication and the valve.
You might work around it by implementing the UI in both modules and refer back to a common business logic, but this is a level of architectural change too broad to fit into this answer.

How to support consuming application configurable authentication providers using spring-security-oauth2

While prototyping out an API & SDK, I've run into this question with several plausible solutions. I'm looking for help with some of the high level architecture. In short, it is guaranteed that some consuming applications of the API are going to want to configure their own authentication providers.
Options that I've been munching on:
Keep resource server and authorization coupled but figure out some way to delegate authentication in one of the authentication providers in my auth manager to the client application.
This sounds promising until I realized that in the particular use case, it's actually necessary that even my providing application not know the user's credentials.
Separate the resource server and make each consuming application responsible for providing an authorization server, and set those endpoints as part of the configuration when registering the consuming app with the resource provider.
This feels like an uncomfortable inversion of what is often desired when using authorization_code grant types. It also would require any "default" authorization providers to be implemented by each consuming application.
Some kind of delegating authorization server that falls back to a default if a client hasn't provided endpoints for their own authorization server.
This would probably be a good solution, but I'm not sure how to do it the "spring-security-oauth2" way or if I'd have to implement a bunch of my own stuff.
Create a default auth server, and optionally allow consuming applications to point to whichever auth server they want.
This seems viable approach in that it offers lots of customization. My concern is, how do I enforce some kind of registry with the resource server? If the auth server is the server that approves consuming applications, but I don't want to let any consuming application implement its own auth server, just some of them. Otherwise non-trusted clients could end up approving themselves!?
In case this influences any guidance, my resource provider will need a fully inflated OAuth2Authentication object (which contains user details and client details).
This image mostly explains what I'm talking about, except I want multiple authorization servers and want to leave it to the consuming application to decide which authorization server to point at. How could I check on the resource-server side of things that the authorization server proxying the requests is an approved authorization server?
ADDENDUM:
I took a look at the existing implementation that's being used for this custom authentication case and I guess we're just reading a token off their session that gets set by their own login service and building their user each time off of that. This sort of customization is a problem in that we're removing customizations from the provider side of things in favor of handling that in the consuming applications. So, I'm looking for solutions so consuming apps can define their own authentication means, to the point of even providing users that the providing application doesn't persist (which leads me to think it may need to be an entire auth server).
That being said, this seems like a potentially unsustainable inverted model (IMHO, the provider should be the maintainer of users and authorization, not the consuming apps). So, I'll probably recommend a more business oriented change.
I believe I have finally come up with a secure and maintainable way of solving this.
Let consuming applications optionally register an authentication callback with the authorization server.
Require incoming authorization requests from that application to the authorization server on behalf of a user to include a token, that token should be stored by the consuming application as a means of referencing whichever user is actively causing the API call.
When an authorization code request is received by the authorization server from an application that has registered one of these callbacks, then POST to that application's registered authentication callback and include the token that was provided by the consuming application in the request.
The consuming application should take the token that was POSTed to it's registered authentication callback and look up the corresponding user, and return a response containing the full user object on whose behalf the providing application should operate (or some kind of error code if the token is invalid).
The authorization server should then generate an authorization code and return to the callback uri submitted with the authorization code request. This means we're back on track according to step 4 in the diagram in the original question. The remaining steps can be carried out as-is.
There is a remaining question of how this might be implemented to take advantage of as much of the spring-security-oauth2 framework as possible while still achieving this extension.

Does Joomla have an application-wide common shared storage or cache?

My server needs to log-in to another server (for accessing payment API). Result of successful log-in operation is a session token that is valid for 25 minutes.
Where can I store this session token so that it is available across multiple requests and multiple users? (i.e. user session is not an acceptable solution).
I need some sort of an application state or cache storage.
Just to demonstrate the problem - a file could be used to store this value, but I don't want to deal with concurrency, and security implications this solution comes with. I would prefer an in-memory solution.
You could use either the core JSession or JCache framework objects.
http://docs.joomla.org/JFactory/getSession
http://docs.joomla.org/Using_caching_to_speed_up_your_code
http://docs.joomla.org/Cache

Session-based authentication for a RESTful webservice in Glassfish

The Problem
I'm creating an application that runs on Glassfish 3.1.2.2 and exposes a RESTful API in an environment where authentication is expensive. Passing the credentials and authenticating every request isn't feasible - I need a session-based approach.
I'm looking at using BASIC auth and in-memory session replication (the app needs to support deployment in a cluster). In-memory replication seems expensive considering I'm only sharing "logged in" state - every other component of the applicaiton is stateless.
My question is: Is there a better alternative?
e.g. Can I configure Glassfish to persist session state to a database, instead of using in-memory replication?
I've considered a "session as a resource" approach e.g. POST to /session to login, DELETE /session/{id} to logout. This provides more control, however it's more difficult for the service consumers (vs something like BASIC auth).

Does Varnish Handle User Web Sessions

I've had 2 sysadmins from 2 large hosting organizations tell me that Varnish will handle session sharing between web servers. I can find nothing online to support this and in fact found this where the guy specifically says it does not. I cannot tell if the guy is a Varnish employee or just a contributor or what.
Just looking for more verification on this point.
A session allows you to store many things (shopping carts, logged in user, etc), and is commonly identified by a cookie (e.g. sessionid). A web server knows how to get a session using this sessionid (and can access/update your shopping cart), but varnish only handles cookies. Varnish can do load-balanced lookups to backends, regardless of the cookie values or based on some rules (you need to write you own varnish config).
However, a challenge in session sharing between web servers is whether a web server can access sessions created/updated by another web server. In many Java Web Containers, sessions are by default stored in memory (of only one web server), with load balancers implementing some kind of 'sticky session' mechanism (sending a user with a session to a specific back-end all the time, can be easily setup with varnish). Another option is to store the (serialized) session values in a shared database, so they can be retrieved by any backend (and will keep working if a web server goes down). A third option is to completely serialize the session into a cookie and stop using sessionids, but this is complex (limited size, bandwidth, security requires some signing mechanism, but scaling is great).
All approaches have advantages and disadvantages. You have to choose, varnish supports any option but will not 'automagically' do what you want, so prepare to write a bit of varnish configuration...
If you would describe how you want to load balance, or what you try to achieve, you could get a more specific answer.

Resources