Spring Websocket: how to customize session disconnect message? - spring

I really wonder if there is a way to customize a message in SESSION_EXPIRED_STATUS from WebSocketRegistryListener. The default implementation is follow:
static final CloseStatus SESSION_EXPIRED_STATUS = new CloseStatus(
CloseStatus.POLICY_VIOLATION.getCode(),
"This connection was established under an authenticated HTTP Session that has expired");
The Spring Security and Spring Session mechanisms are:
User logouts
The corresponding session is invalidated in session repository
WebSocketRegistryListener catches SessionDestroyedEvent and closes all websocket sessions for previously destroyed http session (with close status SESSION_EXPIRED_STATUS)
So, in my application I should customize such behavior, because not only the user can invalidate his session, but also admin is able to do it. Or session can be invalidated by timeout. And for every case I should send messages with different reasons. Can someone help me?
I found WebSocketSessionDecorator with close(CloseStatus status) but I don't know to add it to decorators list for websockets.

Related

Is there a way in spring to destroy a http session if another login attempt of a logged in user comes?

For our application with spring-boot (2.1.4) it is important to us that a user can only be logged in once.
This was relatively easy to configure and works great in relation with REST requests.
http
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(false)
.sessionRegistry(sessionRegistry());
Much of the communication runs through websockets, and getting here starts our problem.
The view of our browser app changes when the websocket connection is disconnected. On the server side the websocket handshake is disconnected if the http session is invalid.
As I understand it, if a user logs in again with an already logged in user, the http session remains valid until the next REST request. I would like the http session to terminate independently from requests.
I have a workaround where I check every AuthenticationSuccessEvent if there are already sessions of this user and terminate them. This approach works, but I don't like it.
Thanks a lot for your help!
A relatively blind guess, but have you tried changing the sessionFixation? It should create a completely new session, without copying over old attributes, on an authentication attempt.
http.sessionManagement()
.sessionFixation().newSession()
;

opening modal from server side, grails

I am trying to show modal after session expired. I am using filters to catch that session has expired:
def filters = {
all(controller:'graphs', action:'*') {
before = {
if (session.expired) {
//some code to invoker modal
return false
}
}
}
}
Modal should notify the user that session has expired and redirect to main page. Any suggestions on how to invoke modal?
What you are proposing is very tricky to implement because you need a client-initiated request or session to transmit anything to the client and any such request will prolong the session. I see two possibilities:
Polling
If you don't mind the session being prolonged and just want to make sure the user is still logged in the simplest way would be to implement Javascript polling using setInterval or similar (but make sure the polling stops on first failure or users are at risk getting redirected to the polling endpoint after logging in again, especially if they have more than one tab open). If you don't want to stretch the session you could try a hacky workaround.
Websockets
You could open a websocket connection using an appropriate plugin and keep it open. You need to make sure no session prolonging heartbeats are being sent. Then when the session ends, send a message back through the connection. Note that this will involve more work than polling.

Session timeout after 15 minutes

In my application I use web services to get required information. To actually use this services you have to login first, you get your token - encrypted password, afterwards this token is attached to SOAP requests to identify current user. The thing is, when you do not use service for 15 minutes, your token changes and when you are trying to obtain another bunch of information from the server it denies old token. As a result app do not get required information and throws a heap of errors.
How to send user (load Login.axm) to Login page when token has been changed?
Thank you, Shay Shmeltzer for your answer.
How I solved this problem:
1) First I read how does sessions work in my particular case. I used stateless session which means -
A new session is opened for an initial request and the session remains
open for subsequent requests. Relogin occurs automatically
(transparent to the user) if the session is closed. UsernameToken and
PasswordText must be included as SOAP headers in the initial request
to open a stateless session.
Stateless session management is the best method to use for high-load
Web service applications. Using Stateless mode, the application
provides the username and password only once, that is for the initial
request. A session is opened on the server and is dedicated for this
user.
In the response Siebel Business Applications return the SessionToken,
which is an encrypted string containing the information about
username, password, and timestamp. For subsequent requests the
application must use the SessionToken to reuse the session.
For security reasons SessionTokens are regenerated for each response.
The application must provide the last received SessionToken for the
next request.
The SessionToken-Siebel session map is maintained in the Siebel Web
Server Extension (SWSE); based on the SessionToken value SWSE sends
the request to the correct Siebel session (task).
Although the session is persistent, authentication happens for each
request (SWSE decrypts the UserName and Password from the
SessionToken).
the main problem was :
NOTE: Reconnecting or automatic logging in again will only happen if
the token has not timed out. If it times out, then the user must
manually log in again. Token timeout must be greater than or equal to
session timeout. For more information on session token timeout, see
Session and Session Token Timeout-Related Parameters.
in my case standard session token live time was 15 minutes.
That is why I included counter in my code and checked it before each request. If counter time > 15 minutes, I sent log in request to the server to get new session token. The reason, I did not change current page to log in page straight away after the counter exceeds 15 minutes is: place in code, where I check counter is already initiated by the bindings to get required value to render it, so if your token has expired you will get a heap of errors. That is why firstly I renew the session sending log in request, get active session token and put it into the last request which is requested by binding. After app renders page without any errors, it shows pop up message "Session has expired" and goes to log in page.
You can programmatically set the soap header being sent to your SOAP service from ADF Mobile - http://docs.oracle.com/cd/E37975_01/doc.111240/e24475/amxwebservices.htm#CHDIBIIE

How to do custom action before session invalidation (time-out)?

I want to store some information of current session's user when a session is getting invalidated (because of time out). How can I do that?
If this helps, I'm using Spring Security 3.1. So if there is any configuration in Spring I'm having no trouble understanding that.
There is a thing in Spring Security as Session Expiration. When a session expires, a filter catches it and I can have my desired information from it.
However the problem is when a session gets invalidated (because of timeout). Because, for the next request there will be a new session created and I'm not able to have access to the old one. I want to know how I can customize session invalidation ?

Maintain session in grails

How to maintain session in my grails application. Here is my requirement.
I have to generate session id (in server side) based on the user-name (which comes from client side while log-in).
After log-in, the server should pass the session id to client and sets timer to validate the session.
For every request, the client should pass the session id to server, so that the server is able to check whether the session is alive or not based on the timer.
If the session is valid, the server should process the request and has to increment the timer.
If the session in invalid, the request should not be processed by server.
Please let me know if you any idea/tutorial/suggestions.
Thanks in advance...
This looks exactly how the http session behaves, so you have that functionality out of the box. Just use the session variable to access session attributes. (see here). And this question tells you about how to configure the timeout.

Resources