Reputation: 1697
Update question description to be more specified and detailed.
I have a weblogic 12c, configured with one cluster, 4 node instances in the cluster, Default Load Algorithm is Round Robin, Replication Type is MAN. I deploy one web application on all 4 nodes.
What I design at first time is:
Execute logout related business logic once user session got invalidated. Put logic code inside "sessionDestroyed" method of SessionListener.java which implements HttpSession Interface. As you know, session got invalidated could be caused by 2 case, one is manually logout, another is J2ee container trigger the time out. My issue is occurred because of the 2nd case.
Issue:
The business logic code inside "SessionDestroyed" event is executed twice for one user time out, which is not expected and result in business error. What I found is Primary Http Session on the node A and Backup Session on the node B both trigger the weblogic "SessionDestroyed" event.
Question:
Attach the Log, you can see the first and second line is primary session, the third line is backup session, which can be proved by the session id in the line tail.
DEBUG Oct-20-17 01:53:40 [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-27 ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022 Created at Fri Oct 20 01:53:40 EDT 2017
DEBUG Oct-20-17 02:54:05 [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-46 ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022 Destroyed at Fri Oct 20 02:54:05 EDT 2017
DEBUG Oct-20-17 02:55:12 [[ACTIVE] ExecuteThread: '17' for queue: 'weblogic.kernel.Default (self-tuning)'] (AMCSessionListener-46 ) - Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!173379423!1400921280!1508478820022 Destroyed at Fri Oct 20 02:55:12 EDT 2017
Below is my weblogic configuration:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app
xmlns="http://www.bea.com/ns/weblogic/90"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-web-app.xsd">
<session-descriptor>
<cookie-path>/AppName</cookie-path>
<persistent-store-type>replicated</persistent-store-type>
<http-proxy-caching-of-cookies>true</http-proxy-caching-of-cookies>
<cookie-secure>true</cookie-secure>
</session-descriptor>
</weblogic-web-app>
This is my session configure in the web.xml inside web application:
<session-config>
<session-timeout>60</session-timeout>
</session-config>
This is my SessionListener.java:
public class SessionListener implements HttpSessionListener {
private static Logger logger = Logger.getLogger(SessionListener.class);
@Override
public void sessionCreated(HttpSessionEvent se) {
if (logger.isDebugEnabled()) {
logger.debug("Session: " + se.getSession().getId() + " Created at " + (new java.util.Date()));
}
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
/**
* The business logic code related to logout action
* would be executed twice here, this is not what I want.
**/
if (logger.isDebugEnabled()) {
logger.debug("Session: " + se.getSession().getId() + " Destroyed at " + (new java.util.Date()));
}
}
}
This code for manually logout:
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView logout(HttpServletRequest request,
HttpServletResponse response) throws Exception {
...
// Business Logic for Logout
...
request.getSession().invalidate();
CommonViewObject vo = new CommonViewObject();
return renderReponse(request, response, vo, "Login");
}
Any suggestion would be appreciated. I need address the issue, thank you!
Upvotes: 4
Views: 1226
Reputation: 3364
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!-1795465203!1400921280!1508478820022
Session: wIc4WB62vlaYR_tMRMIc0WpBHchh5fbwpinxgaig4mJRJFhlPUcj!**173379423**!1400921280!1508478820022
Third log line indicates the session being created in different primary jvm / node ( 173379423 ) compare two first two (-795465203).
this may not relate to the session.invalidate calls rather it has problem of creating two session (two different primary node) and expired after time out
I could think of two possible use case
UPDATE:
- Why backup session not trigger session created event? 2. Ideally, is that backup session should timeout with primary session transparently?
There is no second session being created!!.
Let me try to explain the flow.
Node A Generates the session and marked as primary creates Secondary Backup based on its cluster Ranking ( Assume Node B) and pass sessionid as part of Cookies for further communication.
Further Requests to LB , LB would check the Cookies and based on Server identifier its routes the traffic to the Node A
Node A went Bad / connection issues between Lb to Node A , Now LB cannot route based on Cookie's information , so LB can pick any node based on Round Robin and sends the request to an new Node ( Node D) . At this point Node D pulls session from Secondary based on Cookie information being passed as part request and marked as primary and Node B would remain secondary.
HttpClusterServlet
proxy ( for example apache proxy) and used and (Weblogic Plugin (HttpClusterServlet
)) to do load balancing in front your weblogic , then HttpClusterServlet
should able to collect your secondary server information ( host and port) and route the traffic to secondary back server. Now Node B would become primary and new secondary would picked based on Node B's cluster ranking.All session replications should be transparent to the client and there is no second session created in above case.
Note** , in both the cases (LB / Proxy based routing ) the session created in Node A considered as Orphaned , since the session got new primary and secondary . So when users session get invalidate it would invalidate in both current primary and secondary Nodes.
Weblogic documentation provides additional information abt this use case.
Would suggest to track the session based on access log / applications logs to verify when the calls moved to next node. Also make sure LB health monitor request in access logs during the same time period
Would also suggest to make sure the LB configured with Cookie persistent profile.
Upvotes: 0
Reputation: 2899
I guess you are using the default spring security configuration which by default enables CSRF check, so you may need to disable it and check again
http.csrf().disable()
Upvotes: 0
Reputation: 31397
If you force the user to logout via the invalidate()
method, then HttpSessionListener sessionDestroyed() method is called twice, once when they logout, and a second time after some delayed time period.
This occurs if after the logout you redirect the user back to a web page within your application. What you're essentially doing is starting another session (which may not be immediately obvious if you haven't added security/authentication requirements to all your web pages), and the delayed second call of the sessionDestroyed() method is a timeout occurring.
The simple solution, on logout redirect the user to a web page outside of your application.
You may be interested to look :
JDev/ADF: How to log user login/logout/timeout to the database
JSP Servlet session invalidate() does not make session null
Upvotes: 1