Trouble with session attributes getting replicated in Tomcat 6 - session

I have configured Tomcat 6 with in-memory session replication. I am also using IIS 7 (I know, I know) and the AJP connector via isapi_redirector. The cluster is working properly and I am able to replicate session attributes using the SessionExample in the examples war. The problem is that I am unable to do the same in my custom application. I have added the distributable tag to the web.xml file on both servers in my test cluster. However, I don't see any message in the logs mentioning the attributes getting sent to the cluster (I see them for SessionExample). The only primary differences that I can see in my app from the examples:
The examples war uses servlet 2.5. I am still required to use 2.4.
My application uses SSO and requires the user to login.
The application is a portal application.
Also, in the code of the application, I am setting a simple string in the attribute, so nothing fancy.
So, I was wondering if anyone has some tips to get this working?
Thanks
Here is the cluster section within of my server.xml:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="6">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Membership className="org.apache.catalina.tribes.membership.McastService"
address="228.0.0.104"
port="45564"
frequency="500"
dropTime="10000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="auto"
port="4000"
autoBind="100"
selectorTimeout="7000"
maxThreads="6"
timeout="15000"/>
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"
timeout="70000"/>
</Sender>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/apache-tomcat-6.0.37/war-deploy/war-temp/"
deployDir="/apache-tomcat-6.0.37/webapps/"
watchDir="/apache-tomcat-6.0.37/war-deploy/war-listen/"
watchEnabled="true"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

Sorry. I found the issue. I was expecting to see messages in the log regarding the creation of the session attributes. I didn't realize that the examples project had a session listener that was outputting the messages to the log. I was thinking that it was simply from the log level that I had set.
Thanks to anyone who read this post.

Related

httpsession lifecycle events not working after using my custom UserDetailsService

I've created my own UserDetailsService and UserDetails implementations and hooked it up. I can create users, and login as users. However, if I login, logout, and then login again, I'm getting a redirect to a timeout error page. This is because I'm preventing concurrent logins, but it's not working - it used to with the "hello world" auth examples, but now with my own implementations that piece has stopped working correctly for some reason. Spring basically thinks there are 2 sessions when I login, logout, and login again.
Now - I thought this was all handled automatically ....perhaps using your own UserDetailsService means you actually have to implement session management somewhere else as well? I'm sort of blown away that's not mentioned in the docs or in the book Spring Security 3.1 so I'm assuming I'm missing something.
This is in my web.xml bit for listening to session life cycle events
<!-- This listener updates spring-security on httpsession lifecycle events,
in this case to ensure each user can have only 1 session at a time. -->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
and this is in my security.xml to prevent concurrent logins
<!-- This prevents the user from logging in more than once simultaneously -->
<security:session-management
invalid-session-url="/timeout.htm">
<security:concurrency-control
max-sessions="1" error-if-maximum-exceeded="true" />
</security:session-management>
My logout in the security context file is
<security:logout logout-url="/logout"
invalidate-session="true" delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"
logout-success-url="/login.htm?logout" />
I've tried a few permutations of that. None seem to work. invalidate-session="true" is the default value, so I shouldn't even have to specify this. But it doesn't seem to be happening.
O.k., I just reverted everything to try and do in-memory auth and I'm getting the same errors. Meaning, I'm not using my custom implementations anymore. Sorry - I clearly have something wrong somewhere...and this is proving extremely difficult to find. I might have to start from scratch.
Do I have to do something special on logout with my custom UserDetailsService?
Any feedback or guidance is much appreciated.
To my understanding the error-if-maximum-exceeded attribute should be false. Settings the value to false will cause the original session to expire instead of throwing a exception as explained in http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html#d0e7768
I discovered it was a conflict between using <session-management> in my configuration and my servlet container. I'm using STS 3.5 (custom Eclipse for Spring projects) with vFabric server that runs in the IDE. The Reference documentation did not refer to this in the actual Session Management section (Section 8). However, buried in Section 4 on auth is this little gem:
Note that if you use this mechanism to detect session timeouts, it may falsely report an error if the user logs out and then logs back in without closing the browser. This is because the session cookie is not cleared when you invalidate the session and will be resubmitted even if the user has logged out. You may be able to explicitly delete the JSESSIONID cookie on logging out, for example by using the following syntax in the logout handler:
<http>
<logout delete-cookies="JSESSIONID" />
</http>
Unfortunately this can’t be guaranteed to work with every servlet container, so you will need to test it in your environment
Well, apparently it doesn't work in STS 3.5
At first I tried to eliminate sections of my <session-management> tag so I could just control concurrency (i.e. have the user only able to log in with one session at a time). However, I just kept getting errors.
So, at this point I've removed the session management stuff altogether and will come back to it when ready to deploy.

Redis as a session store in glassfish

I got an open-source component called tomcat-redis-session-manager can store http session in redis, to provide high-availability in many tomcat servers.
So I want to find if there is a way to store glassfish http session in redis or memcached.
But I have not find what is the http session creation or acquire interceptor in glassfish.
Can anyone tell me how?
Tomcat does it by adding the following in context.xml
<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
host="localhost"
port="6379"
database="0"
maxInactiveInterval="60"
/>

Simple axis2.xml for Axis2 embedded in webapp

I am developing a webapp with an embedded webservice with Axis2 using Maven.
The service implementation is a POJO with RPC-style interaction, the target appserver is Tomcat running the Axis2 servlet.
The "Hello world" works but now I need to configure some global axis2 settings in the axis2.xml file (placed under WEB-INF/conf).
Please provide or point to a simple configuration for axis2.xml for this common environment.
The default taken from the binary distribution has too many features activated (hotdeploy?) and also causes this problem:
<soapenv:Reason>
<soapenv:Text xml:lang="en-US">
The ServiceClass object does not implement the required method
in the following form: OMElement ping(OMElement e)
</soapenv:Text>
</soapenv:Reason>
As a reference: http://axis.apache.org/axis2/java/core/docs/servlet-transport.html says to configure the servlet transport in this way, but it does not solve the issue.
<transportReceiver name="http" class="org.apache.axis2.transport.http.AxisServletListener"/>
Apparently the problem is that the default axis2.xml sets raw xml messageReceivers, instead of the RPC ones.
Try to add this to the services.xml for the developed service, should fix the problem.
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
"Solution that worked for me was adding the operation tag in the service.xml against the Java Service method name:
<operation name="sayHello" >
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>
<parameter name="ServiceClass" locked="false">com.learning.webservices.pojo.HelloService</parameter>

Changing JSESSION ID with Tomcat 7

According to the tomcat docs, tomcat7 is not vulnerable to session fixation attack. But my tomcat 7.0.25 as well as 7.0.27 is vulnerable to this attack. JSESSIONID cookie value is not getting changed on successful login.
I added following Valves to my conf/context.xml. But this didn't work. Please help me.
<Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="true" />
<Valve className="org.apache.catalina.authenticator.SSLAuthenticator" changeSessionIdOnAuthentication="true" />
<Valve className="org.apache.catalina.authenticator.SpnegoAuthenticator" changeSessionIdOnAuthentication="true" />
<Valve className="org.apache.catalina.authenticator.DigestAuthenticator" changeSessionIdOnAuthentication="true" />
<Valve className="org.apache.catalina.authenticator.FormAuthenticator" changeSessionIdOnAuthentication="true" />
I have also come to know that JSESSION ID cookie value only changes on authentication. What does authentication means ? Is it switching the application from http to https ?
Is there anything already built which can change the the jsession id value on login ? Right now I am changing this via code.
Thanks in advance. Please let me know if you need more info.
Regards,
Prashant Gupta
Are you sure your application uses server security.
These configuration only affect this behaviour if you're using it.
If your authentication uses for example custom or spring security authentication they will not apply and you will have to do this yourself.
For example in spring sec there are parameters for that.
Regards

Is tomcat clustering only way for session replication?

I tested Tomcat Clustering for session replication on ubuntu servers with apache as front end load balancers. From my testing experience I say it's better not using tomcat clustering but running each node as standalone not knowing one another without any session replication as I felt it's slow, takes much time to startup tomcat service and consumes more memory. And the FarmDeployer is not reliable always in deploying and whole configuration should be placed under<Host></Host> element for farm deployer to work and also for each virtual hosting and thus a huge server.xml file. Below is the tomcat virtual hosting with cluster configuration from one of the node I used.
<Host name="site1.mydomain.net" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Logger className="org.apache.catalina.logger.FileLogger"
directory="logs" prefix="virtual_log1." suffix=".log" timestamp="true"/>
<Context path="" docBase="/usr/share/tomcat/webapps/myapp" debug="0" reloadable="true"/>
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<Manager className="org.apache.catalina.ha.session.DeltaManager"
expireSessionsOnShutdown="false"
notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.1.8"
port="4001"
selectorTimeout="100"
maxThreads="6"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
<Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
<Member className="org.apache.catalina.tribes.membership.StaticMember"
port="4002"
securePort="-1"
host="192.168.1.9"
domain="staging-cluster"
uniqueId="{0,1,2,3,4,5,6,7,8,9}"/>
<!-- <Member className="org.apache.catalina.tribes.membership.StaticMember"
port="4002"
securePort="-1"
host="192.168.1.9"
domain="staging-cluster"
uniqueId="{0,1,2,3,4,5,6,7,8,9}"/> -->
</Interceptor>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
<Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
tempDir="/usr/share/tomcat/temp/"
deployDir="/usr/share/tomcat/webapps/"
watchDir="/usr/share/tomcat/watch/"
watchEnabled="true"/>
</Cluster>
</Host>
Is Tomcat clustering good to use on production or is there any alternate way for session replication?. Or I'm missing anything in the above configuration which could be fine tuned?
Any ideas are welcome. Thanks!
One session-failover / session-replication solution for tomcat is memcached-session-manager (msm), supporting both sticky and non-sticky sessions. msm uses memcached (or any backend speaking the memcached protocol) as backend for session backup/storage.
In sticky mode sessions are still kept in tomcat, and memcached is only used as an additional backup - for session failover.
In non-sticky mode sessions are only stored in memcached and no longer in tomcat, as with non-sticky sessions the session-store must be external (to avoid stale data).
There's also special support for membase / membase buckets, which is useful for hosted solutions where you get access to a certain bucket with the appropriate authentication.
Session serialization is pluggable, so you're not tied to java serialization (and classes implementing Serializable). E.g. there's a kryo serializer available, which is one of the fastest serialization strategies available.
The msm home page mainly describes the sticky session approach, for details regarding non-sticky sessions you might search or ask on the mailing list.
Details and examples regarding the configuration can be found in the msm wiki (SetupAndConfiguration).

Resources