In my application I have an embedded jetty server (version 8.1.2) running a web application that uses spring web security.
The jetty server is configured to use the JDBCSessionManager
One of the security filters that spring employs is a subclass of AbstractAuthenticationProcessingFilter, in it, it has a SessionAuthenticationStrategy which by default is a SessionFixationProtectionStrategy. This protection strategy creates a new session, as a copy of the original session and invalidates the old one.
Now when I try to login to the web application, I see that a new session is created, but the authentication attributes that are added to the new session are not written back to the database. Moreover, I see that the old session is written to the database with new attributes even though it was invalidated.
Finally, when a new http request arrives as part of the new session, it does not pass authentication because of the above.
After some investigation, I found that this behavior does not happen in older versions of jetty (I tried 7.1.4), and I see that the new session data is written to the database.
I could of course solve this issue by any of the following:
Use an older version of jetty
Disable the session fixation protection strategy
Use the default session manager instead of the JDBCSessionManager
But assuming non of the above options are valid for me, I was wondering if there is any solution to this problem.
Thanks!
Resolved in newer releases of jetty 8, at least 8.1.6 :)
Related
I am using Spring Security and I have created a ApplicationListener for HttpSessionDestroyedEvent (for logout and session expiry events). But this listener's onApplicationEvent method is called on login also which looks like a inappropriate behavior. How do I make this working. Below is the code:
public class MySessionDestroyListener implements ApplicationListener<HttpSessionDestroyedEvent> {
#Override
public void onApplicationEvent(HttpSessionDestroyedEvent httpSessionDestroyedEvent) {
httpSessionDestroyedEvent.getSecurityContexts();
// business logic
}
}
You should be prepared to that. The servlet container generally creates a session before the user is connected. When spring-security authenticates the user, it first close that previous session and creates a new one.
That means that an event HttpSessionDestroyedEvent is triggered both on login and logout. You can differentiate those 2 kinks on event by storing for example the user name in session. If it is present, the session was a regular one and it makes sense to call your business logic, if not it was just a technical one and you shoud just ignore it
If your login page uses a HTTP session in a Servlet 3.0 or older container, the Session Fixation Attack Protection will destroy this session and create a new one (migrateSession), see Spring Security Reference:
Session Fixation Attack Protection
Session fixation attacks are a potential risk where it is possible for a malicious attacker to create a session by accessing a site, then persuade another user to log in with the same session (by sending them a link containing the session identifier as a parameter, for example). Spring Security protects against this automatically by creating a new session or otherwise changing the session ID when a user logs in. If you don’t require this protection, or it conflicts with some other requirement, you can control the behavior using the session-fixation-protection attribute on <session-management>, which has four options
none - Don’t do anything. The original session will be retained.
newSession - Create a new "clean" session, without copying the existing session data (Spring Security-related attributes will still be copied).
migrateSession - Create a new session and copy all existing session attributes to the new session. This is the default in Servlet 3.0 or older containers.
changeSessionId - Do not create a new session. Instead, use the session fixation protection provided by the Servlet container (HttpServletRequest#changeSessionId()). This option is only available in Servlet 3.1 (Java EE 7) and newer containers. Specifying it in older containers will result in an exception. This is the default in Servlet 3.1 and newer containers.
When session fixation protection occurs, it results in a SessionFixationProtectionEvent being published in the application context. If you use changeSessionId, this protection will also result in any javax.servlet.http.HttpSessionIdListener s being notified, so use caution if your code listens for both events. See the Session Management chapter for additional information.
There are some solutions for that problem:
don't use session for login page (in most cases not possible)
update to Servlet 3.1 container
change the Session Fixation Attack Protection to none(not recommended)
adopt your business logic
Orbeon is integrated into another webapp. oxf.http.state is set to none.
When loading a form in form runner, external session cookies are not forwarded to the persistence. Despite that oxf.http.forward-headers and oxf.http.forward-cookies are set to according values.
When loading a simple form which isn't rendered by form runner the cookies are nicely forwarded with the requests in preprocessing step to the same server.
And after loading a simple form and forwarding session cookie atleast once, all the request from form runner also contain that cookie till the session expires.
So the question is - is it possible to forward external session cookies to the same server from form runner to custom persistence layer?
Or the only way is to make a dummy request each time to add the cookie to the http client?
As mentioned in a comment, this looks similar to issue #1070, that was marked fixed for 4.3, as the problem wasn't happening with that version. So I recommend you upgrade to 4.3.
If the problem persists with the latest version, I'd recommend you update your question with specific steps we can follow to reproduce this.
I have an application developed in Grails (v1.3.7) and we used Spring Security Core (v1.2.6) plugin for authentication. After building .war file, I have deployed the application in a standard tomcat server (v7.0.22). The application runs fine.
I know that I can configure Session timeout period in web.xml either before building the application or in the tomcat server itself. But, I want (additionally) to redirect any page to the log-in page automatically whenever the Session is timed out. Because, if the Session times out and users click on any links or simply refresh the current page, they get a tomcat error.
Can anyone suggest a way to resolve it easily? Is there any configuration (like expired-session-url) in Tomcat or Spring Security Core that does the job?
I have search in the plugin doc site, plugin blog site but nothing found. This site suggest that I would require to add a listener in code and I would hate to do that and would like to use a simple configuration like this. Can anyone guide anything?
Thanks in anticipation
Http is stateless protocol, and session is just a marker stored on client cookies (+ local db), and you can't handle this as an event. 'new client' and 'session expired' is the exactly same, it just means that you can't identify browser for current request. For most cases it means also that user is not authenticated (for raw Spring Security Core, at least)
For you case, you already have session expired handler, it's when you're getting this tomcat error. Just handle this error, and redirect user to login page.
Btw, if you have proper Spring Security configuration, it must redirect all non-authorized users to login page. And seems that you have made something wrong with your app architecture, if you have authenticated user, but still having some user datails in standard tomcat session. There at least two ways: avoid your own user session, or make some kind of session-based Spring Security authentication config.
We are integrating Form Runner/Builder into a project with a custom persistence layer.
Right now we have emptySessionPath="true" set to keep Orbeon and our Java app on the same session.
Orbeon is passing the jsessionid cookie in the persistence CRUD calls... except for the following instance....
User connects to our Java app and logs in, jsessionid cookie is set
User visits an existing form instance at /fr/OurApp/formtest/edit/3eb4ddcf03f2410084e5578adb1e2a7b (Session Cookie is present)
Persistence call is made to our custom persistence layer, but cookie is not forwarded
But, if the user was to first edit the form itself with a call to /fr/orbeon/builder/edit/f40efbe298204d16b6474fcdfea4c9fd which does pass the cookie to the persistence layer
At this point the user can go visit step 2 to complete the form instance and the cookie will persist. It seems that for some reason starting form builder is required to get the cookie to forward to the persistence layer when completing the form?
Any ideas on why the cookie isn't getting passed on step 2?
FYI this is on Orbeon 3.9 CE, also same behavior in 3.8. Using VMWare TC Server (Tomcat). Our java app is a Spring/Grails app.
I am wondering if this might be what's described in this bug (see in particular the comments). Basically, it doesn't seem like you can always reliably produce a JSESSIONID cookie. And as the bug says, we don't have a solution right now.
Do you think the bug corresponds to your case?
I am using Spring Security 3.0.5 and Camel 1.5 (yes, very old but we don't have time to update right now).
In this particular scenario I am uploading a file which hits a Spring Controller which then redirects the request body (which is XML) to an endpoint which is a method in another class. Here is the issue: I had a tester perform an upload but when the GUI listing of files came back it had another person's name as the person who uploaded the file. During debugging I found that in the first Spring Controller the SecurityContext is correct in that it is indeed the credentials for the person performing the upload. After the Camel redirect though the SecurityContext was for another user who happened to have a session in the web app. Obviously this is not good.
So two questions:
Does anybody know what to do or if there is anything I can do using Camel 1.5 to fix this issue?
Why would the credentials of another user from another session be in this session? This question is regardless of Camel.
What http are you using? Can you check if there is a single thread only processing the request at all time, or is multiple threads involved?
And btw Camel 1.5 is EOL, and not support at all anymore.