grails-cookie-session
grails-cookie-session copied to clipboard
When using Spring Security the session gets larger and larger
I'm using cookie-session with spring-security and spring-security-ui.
I have the following settings, as instructed:
grails.plugin.cookiesession.springsecuritycompatibility = true
grails.plugin.springsecurity.useSessionFixationPrevention = false
But the session gets bigger and bigger. For example, just by making a couple of failed logins, the session does not fit on 5 x 2048 cookies anymore and it all bombs out.
How can I tell Spring Security to cleanup after itself?
@tobia This won't answer your question about cleaning up after Spring Security. What we ended up doing was bump up our cookie sizes and cookiecount so that we have a config that is like the following:
grails {
plugin {
cookiesession {
enabled = true
encryptcookie = true
cryptoalgorithm = "#######"
secret = "#######"
cookiecount = 15
maxcookiesize = 4096 // 4kb
sessiontimeout = 28800 // 28800 / 60 / 60 = 8hrs
cookiename = 'gsession'
serializer = 'kryo'
springsecuritycompatibility = true
}
}
}
On the server side we had to increase the maxHttpHeaderSize in our Tomact server.xml to accommodate the larger cookie sizes.
We haven't seen too many exceptions since then.
A snippet of the exceptions that we were seeing: ERROR cookiesession.CookieSessionRepository - An error occurred while deserializing a session
I'm not sure what's going on with spring security - it shouldn't be stashing additional data in the session if a login fails. Have you tried dumping the contents of the session after each login attempt? you should be able to dump the session contents by iterating the keys of the session object from a controller and printing to console. Look out for the object that stores the current identity - it should be anonymous after a failed login.
If that doesn't reveal anything, let me know and I can give you some config options that will log the contents of the session just after the cookies are deserialized.
The problem is quite simple and silly. Session is stored in cookies -> cookies (on server side) are stored in a request -> request(SavedRequest) is stored in a session(by spring) -> session is stored in cookies -> cookies (on server side) are stored in a request -> request(SavedRequest) is stored in a session(by spring)... Should i continue? :D.
To avoid this we should remove 'gsession' cookies from the SavedRequest after spring saves it.
Here's a pull request but it doesn't fix this issue completely. The session still grows up :( https://github.com/benlucchesi/grails-cookie-session-v2/pull/55
Any news regarding this? I've been noticing this same behaviour. Spring Security is probably one of the most used plugins in Grails applications, so I think compatibility with it should be top priority.
Matias,
I posted a work-around for this in another thread.
The issue is with spring security's exception translation filter. I'm still working on a "better" fix for this, which will likely be a new exception translation filter that does aggressively store the entire request on access denied. In any case, here's the work-around. It's worked for other users.
Strategy:
- remove the exception translation filter from spring security. this is the object responsible for storing the current request into the session and the redirecting the browser to the login page
- add a custom url mapping for 500 on spring authentication exceptions and map it to an error handler controller. The handler will function as the access denied handler and redirect to the login page.
- in the error handler method, save the forward uri and redirect to a custom login page with the forward uri on the query string
- in the controller method that renders the login page, pass the forward-uri that came from the access denied handler into a hidden input with the name "spring-security-redirect" in the login form. Spring will pick up this field and perform the redirect for you after a successful login.
To remove the exception translation filter, add this to the Config.groovy grails.plugin.springsecurity.filterChain.filterNames = [ 'securityContextPersistenceFilter', 'logoutFilter', 'authenticationProcessingFilter', 'rememberMeAuthenticationFilter', 'anonymousAuthenticationFilter', 'filterInvocationInterceptor' ] // filter list sans exceptionTranslationFilter
add this mapping to your URLMappings.groovy "500"(controller: "errors", action: "accessDenied", exception: org.springframework.security.access.AccessDeniedException)
If you don't have an ErrorsController.groovy, create one and add this method: def accessDenied(){ redirect uri: "/index/login?redirecturl=${forward}" } replace the uri with your login page
In your login page render the redirecturl into a hidden form tag called "spring-security-redirect".
spring-security-redirect is a special form param picked up by the authentication handler and performs the redirect after successfully authenticating.
Let me know if you run into problems.
Awesome response Ben, works perfectly. Cheers and thanks for your amazing plugin.
Glad it worked!
I'm leaving the issues open until I have the better fix done...
On Thu, Oct 29, 2015, 7:36 AM Matias Radzinski [email protected] wrote:
Awesome response Ben, works perfectly. Cheers and thanks for your amazing plugin.
— Reply to this email directly or view it on GitHub https://github.com/benlucchesi/grails-cookie-session/issues/53#issuecomment-152199380 .
Fixed in https://github.com/double16/grails-cookie-session/tree/release/4.0.0
dependencies { compile 'org.grails.plugins:cookie-session:4.0.0.RC1' }
'cookies' were also present in the headers, so removed that header.