问题
Recently we have faced a serious problem, that one user was served data of another user. This problem is almost impossible to reproduce.
We are using standard logged-users-management provided by Spring-security, and we are sure that the problem isn't in storing user in instance variable or similar concurrency stuff in our app.
We really doubt that the problem is in SpringSecurity or Tomcat itself.
Our front-server is apache httpd, connected to tomcat via ajp connector (mod_jk). We are not doing any load balancing (httpd cares just about SSL, some url rewrites and serving some php modules)
Here is our setup:
## OS
OS Name: Linux
OS Version: 2.6.32-5-686
Architecture: i386
## Apache httpd
Server version: Apache/2.2.16 (Debian)
Server built: Sep 4 2011 20:27:42
## mod_jk
mod_jk/1.2.30 (installed via apt-get)
## JVM
JVM Version: 1.6.0_18-b18
JVM Vendor: Sun Microsystems Inc.
## Tomcat
Server version: Apache Tomcat/6.0.28
Server built: February 12 2011 1443
We blame httpd / mod_jk from this session mix up so our only solution would be to remove apache httpd. But before we leave this popular and widely used configuration, we would like to know if anyone has faced the similar problem.
The only similar problems I have found were in load ballancing or mod_jk.
Have you ever faced some similar problem? Any hints, ideas, links or experience will be highly appreciated. Thanks!
回答1:
One of possible problems may be second login attempt. Consider following case:
- User opens two browser tabs with two login forms.
- Tab 1: do login as user_1. Load some data into the HTTP session.
- Tab 2: do login as user_2. Load some data into the HTTP session.
In most browsers it will be the same HTTP session. So actually you will have data from user_1 and user_2 combined in one HTTP session. Any page that uses session objects may be affected.
You have two options here:
- Prevent this situation. Detect second login attempt and ask user to do logout first. It's easy with Spring Security, see code below.
- If you absolutely need one account per browser tab then you can store your session data in a map per username.
You can prevent second login attempt thanks to Concurrent Session Control fetaure:
<http>
...
<session-management>
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
</http>
Is it already done in your application?
回答2:
If you exclude the concurrent session problem then pretty much the only possibility is that your business logic itself is flawed, and serving another user's data. Please post code samples how the 'current user' is determined, and later used.
EDIT: bugs that manifest themselves only in production are often caused by race conditions (http://en.wikipedia.org/wiki/Race_condition). Ensure that your code uses local variables whenever possible, and employ locking/synchronization where applicable.
回答3:
So far we were not able to reproduce the bug, but we have found that some people faced same problem with mod_jk:
- https://issues.apache.org/bugzilla/show_bug.cgi?id=47714
- http://grails.1312388.n4.nabble.com/Spring-Security-after-log-in-user-changed-and-session-mixed-up-td4636714.html (at the bottom)
So now we are running with this settings:
- JkOptions DisableReuse : http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html
- worker retries = 0 : http://tomcat.apache.org/connectors-doc/reference/workers.html#Advanced Worker Directives
And we are planning to switch mod_jk for mod_proxy_http.
I am leaving this question not-answered, because I can't assure (and nobody facing same problem was able to assure) that the solution fixes the bug.
If anyone could share any information, I would appreciate it a lot! Thanks.
回答4:
When you integrate JSF and Spring, the JSF dependency injection conflicts with Spring dependency injection so Spring rewrote the JSF module that handles that to just wrap Spring DI instead. So when I declare a JSF ManagedBean as Session Scoped, I must also give it a @Controller
annotation so that it is recognized as a Spring Bean as well.
For More info, See this.
回答5:
I've encountered the same problem with Glassfish 3.1.2.2 and Mod_JK 1.2.19
You can reproduce the bug with a JMeter script and a good assertion.
Here is my blog post telling the story : http://jeecookbook.blogspot.com/2013/07/modjk-session-mixed-between-users.html
Using Mod_proxy with this assertion solve the problem : no more mixing detected.
来源:https://stackoverflow.com/questions/14731806/session-mix-up-apache-httpd-with-mod-jk-tomcat-spring-security-serving-dat