New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grails 3 Sample #245

Closed
bobbywarner opened this Issue Jul 24, 2015 · 11 comments

Comments

Projects
None yet
4 participants
@bobbywarner

bobbywarner commented Jul 24, 2015

It appears that the default setup of Spring Session (with Redis) does not work with a new Grails 3 application (following the Spring Boot guide). I have validated that the connection to Redis works (RedisConnectionFactory bean is fine) and I have also validated that the Spring Session filter is being called when hitting a Grails 3 controller, but no sessions are stored in Redis. Please let me know if you have any suggestions for getting Spring Session to work with Grails 3.

@rwinch

This comment has been minimized.

Member

rwinch commented Jul 24, 2015

@bobbywarner Thanks for the feedback. I don't think I have enough information to figure this out. Perhaps a little more details will help.

  • What does your configuration look like?
  • Did you check to see if the cookie was named SESSION instead of JSESSIONID?
  • Did you ensure to add @ComponentScan to your Application class so the @EnableRedisHttpSession is picked up?

I created a Grails3 Sample application in a branch at https://github.com/rwinch/spring-session/tree/gh-245 You can run it by using grails run-app in the samples/grails3 folder. Perhaps that will help resolve your issue?

@erichelgeson

This comment has been minimized.

Contributor

erichelgeson commented Jul 24, 2015

Here is the sample @bobbywarner and I were working off of. erichelgeson/grails3-redis-session@31f15ce

One thing that's different is you have spring-security-starter, we do not. Is that required? (a session is a session, if you're logged in or not)

Thanks for taking the time to create the sample!

@rwinch

This comment has been minimized.

Member

rwinch commented Jul 24, 2015

@erichelgeson Spring Security should not be required. I just used Spring Security because it was the easiest way for me to create a session.

What steps can I perform to create a session with your sample? Spring Session creates sessions lazily (i.e. when HttpServletRequest.getSession() is accessed).

@erichelgeson

This comment has been minimized.

Contributor

erichelgeson commented Jul 24, 2015

I just noticed I didnt checkin my controller, updated - erichelgeson/grails3-redis-session@ace8425

My test was to navigate to:
http://localhost:8080/testSession/index?test=1234
You should see 1234 echoed back
http://localhost:8080/testSession/index
You should still see 1234 echoed back as it's stored on the session
At this time there are no keys in redis though, i'd expect this session to be serialized to redis now.

$ redis-cli keys '*'
(empty list or set)
@rwinch

This comment has been minimized.

Member

rwinch commented Jul 24, 2015

Thanks for the updated sample. This does seem to be a problem. The issue is that the GrailsWebRequestFilter is placed before the SessionRepositoryFilter. This means that the HttpServletRequest that is seen by the controller is not wrapped (thus the HttpSession is not overridden).

You can work around this issue by adding a FilterRegistrationBean that overrides the order. For example:

@EnableRedisHttpSession
@Configuration
public class SessionConfig {

    /**
     * By Default SessionRepositoryFilter is registered as +50, but we need it to be before GrailsWebRequestFilter which is registered at +30. This
     * overrides the default order.
     */
    @Bean
    FilterRegistrationBean springSessionFilterRegistration(SessionRepositoryFilter<? extends ExpiringSession> filter) {
        new FilterRegistrationBean(filter:filter, order: Ordered.HIGHEST_PRECEDENCE + 15)
    }
}

It certainly seems like something we should be able to make easier, but I'm not certain how to best go about it. What are your thoughts @graemerocher ? I'm hesitant to change the default ORDER of the SessionRepositoryFilter to be any earlier as it may not leave enough room for Filters that may need to go before it (there is certainly enough room for Filters after it). Is this something that Grails might be able to help coordinate?

@erichelgeson

This comment has been minimized.

Contributor

erichelgeson commented Jul 24, 2015

👍 Thanks @rwinch, works with that work around. Appreciate your time!

erichelgeson added a commit to erichelgeson/grails3-redis-session that referenced this issue Jul 24, 2015

Working spring-session-redis implementation.
Work around provided by spring-projects/spring-session#245

This is a diff from fresh 3.0.3 grails app.

More info on spring boot and spring session
https://github.com/spring-projects/spring-session/tree/master/samples/boot (this code is pretty much the same and works)
http://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html
@graemerocher

This comment has been minimized.

graemerocher commented Jul 27, 2015

@rwinch The Grails filter is registered at HIGHEST_PRECEDENCE + 30: https://github.com/grails/grails-core/blob/master/grails-plugin-controllers/src/main/groovy/org/grails/plugins/web/controllers/ControllersGrailsPlugin.groovy#L101

Changing that could break things, I'm not sure what can be done here, we could add a check for the presence of the springSessionFilterRegistration but it isn't a great solution.

@erichelgeson

This comment has been minimized.

Contributor

erichelgeson commented Jul 27, 2015

With numbering precedence systems like this there's not a great solution for these types of conflicts. Maybe in a minor release (3.1.x) would be a good time to move the number around (since the work around is straightforward for 3.0.x) We can move this to a grails-core issue as well.

@rwinch

This comment has been minimized.

Member

rwinch commented Jul 27, 2015

@graemerocher @erichelgeson Thanks for the feedback.

Generally, Spring Boot has sorted out most of the Filter ordering issues AFAIK.

However, I think there are likely other issues with the Filter ordering when running in Grails. A few additional Filters that should wrap the request (thus should be before GrailsWebRequestFilter) are Spring Security's FilterChainProxy, HiddenHttpMethodFilter, CharacterEncodingFilter, MultipartFilter.

Additionally, some of these Filters may be dependent on other Filters being before them. For example, if someone uses Hibernate in Spring Security they would want OpenSessionInViewFilter registered before Spring Security. If someone is using localization, then they would want RequestContextFilter registered before Spring Security too (so the error messages are localized).

For these reasons, I think this is something that likely needs fixed in Grails. In light of this additional information, what are your thoughts @graemerocher? Should we create a Grails ticket to try and get this sorted out?

@graemerocher

This comment has been minimized.

graemerocher commented Jul 27, 2015

@rwinch Sure you can create the ticket, I'm just not sure what the solution is. Grails has to have hard coded knowledge of all of the possible filters that could be registered by Spring?

@rwinch

This comment has been minimized.

Member

rwinch commented Jul 27, 2015

@graemerocher Thanks for the response. I'm not sure it is an ideal solution, but at the moment we try to coordinate Filter ordering for any Filter in the org.springframework package (and its subpackages) that is used within Spring Boot. This is unfortunately a manual process that isn't necessarily easy. Sadly, the only alternative I have come up with is making each user manage the ordering themselves (which seems even worse to me).

I went ahead and created grails/grails-core#9137 to track this improvement. I'm going to close this issue in favor of the grails related issue.

@rwinch rwinch closed this Jul 27, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment