Grails Multi-Tenant Plugin & Spring Security Filter
We had a long-standing issue in our Grails project, where the “remember me” functionality was not working as we expected it to. It was behaving very inconsistently. Sometimes the user would be remembered, and sometimes not.
Our application uses the spring-security plugin for authentication, and I initially wondered that there might be a bug in the “remember me” functionality of the plugin. On further investigation, I noticed that the problem was not actually in the spring-security
plugin.
Our application also uses the multi-tenant-core plugin, which resolves the tenant based on the request. The problem was that sometimes the multi-tenant-core
plugin was not resolving the tenant (returning 0
instead) when called within the authentication code of the spring-security
plugin. Therefore, spring-security
was not finding a user by the respective username within the tenant represented by 0
(as such a tenant did not exist).
The reason this was happening was because the multi-tenant-core
plugin has a filter which calculates the current tenant and spring-security
has its own set of filters. The application was behaving as expected when multi-tenant-core
’s filter executed before spring-security
’s remember me filter, and erroneously otherwise. To fix this problem, we had to make sure that the multi-tenant-core
plugin’s filter would always execute before the spring-security filters.
Adding a line to our application’s BootStrap.groovy
did the trick:
1
2
3
4
5
6
7
8
9
10
11
12
13
import org.codehaus.groovy.grails.plugins.springsecurity.SecurityFilterPosition
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
class BootStrap {
def init = { servletContext ->
...
// To make sure it executes before all authentication filters
SpringSecurityUtils.clientRegisterFilter('multiTenantFilter', SecurityFilterPosition.PRE_AUTH_FILTER.getOrder() - 1)
...
}
...
}