ascu
ascu

Reputation: 1139

Discriminator multi-tenant setup with SpringSecurity plugin in Grails

I'm trying to setup a discriminator-based multi-tenant system based on the documentation found in the GORM guide

Do determine which tenant that is using the system I want to use the Spring Security Plugin and show data depending on user id.

This is my tenantresolver:

class MyTenantResolver implements AllTenantsResolver {

    def springSecurityService

    @Override
    Iterable<Serializable> resolveTenantIds() {
        return new DetachedCriteria(User)
                .distinct('id')
                .list()
    }

    @Override
    Serializable resolveTenantIdentifier() throws TenantNotFoundException {
        return springSecurityService.currentUser.id
    }
}

And I add the springsecurityService in the resources.groovy file:

beans = {
    myTenantResolver(MyTenantResolver) {
        springSecurityService = ref("springSecurityService")
    }
}

Unfortunately this causes a circular dependency:

The dependencies of some of the beans in the application context form a cycle:

   grailsCacheFilter
      ↓
   (inner bean)#6c1f419f
      ↓
   urlMappingsHandlerMapping
      ↓
   openSessionInViewInterceptor
┌─────┐
|  hibernateDatastore
↑     ↓
|  hibernateConnectionSourceFactory
↑     ↓
|  myTenantResolver
↑     ↓
|  springSecurityCoreSpringSecurityService
↑     ↓
|  transactionManager
└─────┘

What can I do differently to be able to check against the logged in user?

(Using Grails 3.2.8 and Spring Security 3.1.1)

Upvotes: 0

Views: 661

Answers (2)

Numilani
Numilani

Reputation: 366

You may want to take a look at the sample project over on grails-samples. It has a fully functional "user as tenant" tenant resolver in place to use as a base for your own work.

Upvotes: 0

ascu
ascu

Reputation: 1139

Finally solved it by fetching the session through the RequestContextHolder:

class MyTenantResolver implements AllTenantsResolver {

    @Override
    Iterable<Serializable> resolveTenantIds() {
        return new DetachedCriteria(Customer)
                .distinct('id')
                .list()
    }

    @Override
    Serializable resolveTenantIdentifier() throws TenantNotFoundException {
        User.withTransaction {
            def session = RequestContextHolder.currentRequestAttributes().getSession()
            return User.read(session.getAttribute('SPRING_SECURITY_CONTEXT').authentication.principal.id).customerId
        }
    }
}

Upvotes: 2

Related Questions