What to do to activate persistent sessions? - spring

What should i do in Spring Boot to activate persistent sessions ?
I tried to play with theses properties without luck:
server.session.persistent=true
server.session.store-dir=/some/path/sessions
When i stop the daemon a see a file SESSIONS.cer on the session store-dir which disappears when I restart the daemon, but the user not logged anymore (go to login page).
My Spring boot project is an Oauth2 authorization server (I use Spring Security Oauth2) which is used with the Implicit grant. The session is used to avoid the user the retype its credential (login form) when asking for a token (/oauth/authorize). This is the default behaviour of spring security oauth2
EDIT:
I tried with the following property too without luck:
server.tomcat.basedir=/tmp

To me, it didn't work because the objects i stored in session were not Serializable.
Just check they are.

Object stored in session must implement Serializable along with a fixed serialVersionUID. Otherwise JVM will assign a random serialVersionUID which will be different for each server deployment. Since it is different for each deployment, server will not able to find a previous session and result in creating a new session.
Reference:
Why jvm generates serialVersionUID?

Related

How can I implement Single Sign On (SSO) multi tenancy functionality with Keycloak and Spring Boot OAuth2 clients?

Problem
Implementing SSO login for multiple OAuth2 providers in Spring Boot.
Setup
Two Spring Boot web applications (App1 and App2) that are configured to be OAuth2 clients. Both will communicate with a Keycloak authorization server that has two realms.
Business Requirements
Implement Single Sign-On functionality (SSO).
Multi tenancy with shared user base.
Only one user can access one tenant at any time.
I have two spring boot applications which are OAuth2 clients running in docker containers. We are setting up multiple Keycloak realms that are configured for each tenant. From the Spring side of things, we include the auto configuration properties for two providers where each provider will be mapped to a different Keycloak realm. So the properties will look as follows:
spring.security.oauth2.client.provider.realm1......
spring.security.oauth2.client.provider.realm2......
Behavior
When a user logs into the first application (App1), Spring shows a generated html page. This page shows a list of each provider configured from the application.properties as an option to login to.
A user can select one and is redirected to the Keycloak login page with the realm that was mapped from Spring's provider properties. Then when successfully logged in, the user is redirected back as expected.
We use Spring Mongo session to store the session information and we also see in the Keycloak admin client the realm that shows the active session as well.
When trying to access the other application (App2), Spring does not detect the user or session and will show the same generated html page that shows the providers to select and login to.
When clicking on the same provider (realm), Spring will then find the session and will be redirected to the requested resource and all is well. This part is what I am trying to implement without asking for the provider first. The main reason is to enforce a business requirement where a user in a session can not access more than one realm at a time.
Attempted Solution
Provide a Spring Security login controller that will have a service layer to find the mongo session and then build the OAuth2 link Spring generates when you click a provider from the list.
However, I dont have the user yet. This also becomes a problem when opening a different tab as I dont believe I have any scope to the cookies that were created from the first application as well.
The only other thing I can think of is trying to get the client ip and store that in the session so I can find it later. However, when using nginx proxy configuration, this becomes a problem as I cant seem to get the actual ip and always seem to get the proxy ip instead even with the nginx headers I have seen from documentation.
Question
Is there anyway to find the session and redirect to the requested provider programmatically?
Note: I am currently aware of the keycloak starter dependencies that are available but I was trying to see if there is a more Spring oriented solution with its general OAuth2 client security configuration.
Front end solution
User navigate to app1, app1 detects no user session (need for login), app1 redirects user to app2 with some query parameters indicating purpose of redirect.
App2 receives redirect request and check if session exist (user logged in to app2). Now you can deal with it. redirect back to app1 or display some error, etc.
User not logged in to app2 , app2 redirects back to app1 with indication "show providers"
Symmetrical behavior shall be implemented on app1 too.
Depending on security requirements query parameters can be encrypted to prevent manual url hacking.
If you need further protection Keycloak authentication can be extended with functionality to check your Session storage for already logged in users.

How to store OAuth2 session into database and share it between Spring Boot servers

I want to create a solution based on that tutorial: https://www.baeldung.com/rest-api-spring-oauth2-angular
But it's not clear for me how several Spring Boot servers behind load balanced can share the same token session.
With session cookie the session data can be stored in MySQL and of server goes offline the session will be resumed by another Spring Boot server.
Can we have with OAuth2 the same setup with shared database so that the session data can be shared and switching of severs can be completely transparent for the end users?
Can we have with OAuth2 the same setup with shared database so that
the session data can be shared and switching of severs can be
completely transparent for the end users?
Yes, You just have to define a JdbcTokenStore and use it instead of the default InMemoryStore to store your OAuth tokens. The JdbcTokenStore must use a DataSource which is pointing to a MySQL Database.
Finally if you configure your Spring Boot apps to connect to the same MySQL Database to store Tokens by defining a DataSource you can get it working.
This post could be a good starting point.

Spring Boot w/ KeyCloak and Redis session store

Can someone suggest how to configure a Spring Boot application to authenticate via KeyCloak, and then use Redis as the session store? I've spent a day googling and banging my head on this, and I just don't feel like I'm getting anywhere.
I know how to configure each one independently - i.e. I can make a boot app that auths via KeyCloak, and I can also make a boot app that keeps session in Redis, but I'm not getting them to work together. Is this possible? It seems like it should be. Or is this just not how its supposed to work?
I think my working POC would behave something like this:
start my app
access some resource that forces a login via KeyCloak - access to resource is granted
restart my app
access that same resource but now no login is needed (since session is persisted in Redis)
Thanks for any suggestions.
OK - turns out I'm just not paying attention. I was not using the access/bearer token correctly. There is no need to keep the Spring session around when the bearer token is properly provided in requests.

Stateless front-end grails server?

I have a single grails (3.3.5) web server, and I am interested in improving the availability and I'd like to add another server and put a load balancer in front of it.
Rather than share sessions between servers, or use sticky sessions, i'd like to know if there is a good way to have a session-less front-end server. I don't use sessions for anything other than using spring-security to validate the session token that it is using to identify the user.
I'd like to find a token based authentication system suitable for the front-end such that the token is safe and sufficient for identifying the current user.
I've seen the grails-spring-security-rest plugin which looks promising, but it seems like everyone is using it for back-end rest api calls. Is it also suitable for front-end authentication when you aren't storing application data in the webapp session?
If you don't use the session objects in your controller then tomcat will not create any sessions for you.
Also you can define your controllers to be
static singleton = true
then they will be instantiated not on per-request basis.
Now, if you still want to use sessions, you can use something like Cookie Sessions and keep your data inside the cookies instead of tomcat's memory.
I haven't used the grails-spring-security-rest, but you should be able to tweak spring-security-core to be session-less. You should set scr.allowSessionCreation to false and use remember-me.
Since Grails is built on Spring Boot, you can access all the features of Spring Session (https://docs.spring.io/spring-session/docs/2.0.x/reference/html5/), which includes the ability to share session data between server instances with some data store instead of keeping it in memory.
In those docs you'll find this pointer to a guide with a Grails 3.1 example that uses Redis as the store. https://github.com/spring-projects/spring-session/tree/2.0.3.RELEASE/samples/misc/grails3
Is it also suitable for front-end authentication when you aren't storing application data in the webapp session?
Yes, you can use JWT tokens in your front-end. You need to properly configure the security filters of your controllers so that they are not using cookie for authentication but they are looking for JWT.
See : http://alvarosanchez.github.io/grails-spring-security-rest/latest/docs/#_plugin_configuration for configuration of endpoints that should validate JWT tokens.
Have a look at https://github.com/hantsy/angularjs-grails-sample/wiki/3-basic-auth for a stateless example with Angular.

Invalidating Http Session on maximum allowable session for a user

I developed a web application using spring and hibernate. By using Spring Security , i am restricting one session per user. When user try to attempt multiple login then old session will be invalidated and new one will be active.I have registered HttpSessionListener in my web.xml file.In sessionDistroyed method i am writing some functionality that will be executed when Http Session getting invalidating.
Now problem is when a single user try to do multiple login ,spring security expiring the old session but not invalidating the old session.So in that case sessionDistroyed method not being executed.But i want sessionDistroyed method to be called when spring security expiring the old session.
Can anyone please help to resolve this problem.

Resources