0
votes

I can create a secure, multi-tenant web app with Grails by :

  • setup spring security plugin,
  • setup Multi-tenant plugin (via multi-tenant install and multi-tenant-spring-security)
  • update config.groovy :

    tenant { mode = "multiTenant" resolver.type = "springSecurity" }

  • add : Integer userTenntId in User domain

  • add a domain class for tenant Organization
  • associate the tenants with Organization
  • Edit BootStrap.groovy.

Everything works fine in multi-tenant mode, but how to use mode = "singleTenant" ?
This configuration sound not working :

tenant { mode = "singleTenant" resolver.type = "springSecurity" }


Edit :

I try this config :

tenant {
  mode = "singleTenant"
  resolver.type = "springSecurity"
  datasourceResolver.type = "config"

  dataSourceTenantMap {
    t1 = "jdbc:hsqldb:file:custFoo"
    t2 = "jdbc:hsqldb:file:custBar"
  }
}

But I get :

ERROR errors.GrailsExceptionResolver  - Executing action [list] of controller [org.example.TicketController]  caused exception: java.lang.StackOverflowError

and :

Caused by: java.lang.StackOverflowError
    at org.grails.multitenant.springsecurity.SpringSecurityCurrentTenant.getTenantIdFromSpringSecurity(SpringSecurityCurrentTenant.groovy:50)
    at org.grails.multitenant.springsecurity.SpringSecurityCurrentTenant.this$2$getTenantIdFromSpringSecurity(SpringSecurityCurrentTenant.groovy)
    at org.grails.multitenant.springsecurity.SpringSecurityCurrentTenant$this$2$getTenantIdFromSpringSecurity.callCurrent(Unknown Source)
    at org.grails.multitenant.springsecurity.SpringSecurityCurrentTenant.get(SpringSecurityCurrentTenant.groovy:41)
    at com.infusion.tenant.spring.TenantBeanContainer.getBean(TenantBeanContainer.java:53)
    at com.infusion.tenant.spring.TenantMethodInterceptor.invoke(TenantMethodInterceptor.java:32)
    at $Proxy14.getConnection(Unknown Source)
1

1 Answers

0
votes

I'm still testing the multi tenant plugin (core) in singleTenant mode but it's already running altho not tested throughlly.

Here are the steps:

1- install spring security plugin, run grails s2-quickstart to set up the roles

2- Install multi-tenant-ehcache plugin and change your cache.provider_class in Datasource.groovy to:

cache.provider_class = 'grails.plugin.multitenant.ehcache.cache.MultiTenantEhCacheProvider'


3- Install multi tenant (core) plugin and set up the datasource resolver plus the dns resolver i did it in a static way. Plus altho in the plugin doc says we can configure the dataSoruceTenantMap like this:


dataSourceTenantMap {

  • t1 = "jdbc:mysql://localhost/ets_dev1"

  • t2 = "jdbc:mysql://localhost/ets_dev2"

}
didnt worked for me so i used the jndi option through grails.naming.entries in the config:

/** Config.groovy **/

grails.naming.entries = [
"jdbc/lh_dev1": [
type: "javax.sql.DataSource",
auth: "Container",
description: "My data source",
driverClassName: "com.mysql.jdbc.Driver",
url: "jdbc:mysql://localhost:3306/lh_dev1",
username: "xxx",
password: "xxx",
maxActive: "100",
maxIdle: "30",
maxWait: "10000"
],
"jdbc/lh_dev2": [
type: "javax.sql.DataSource",
auth: "Container",
description: "My data source",
driverClassName: "com.mysql.jdbc.Driver",
url: "jdbc:mysql://localhost:3306/lh_dev2",
username: "xxx",
password: "xxx",
maxActive: "100",
maxIdle: "30",
maxWait: "10000"
]
]

//MultiTenant plugin configuration

tenant{

    mode = "singleTenant" // "singleTenant" OR "multiTenant"
    datasourceResolver.type = "config" //This is the default and can be omitted

    dataSourceTenantMap { 
        **t1 = "java:comp/env/jdbc/lh_dev1"****
        **t2 = "java:comp/env/jdbc/lh_dev2"**
    }

    resolver.request.dns.type = "config"  //This is the default
            domainTenantMap {
                      lh_dev1 = 1
                      lh_dev2 = 2

            }
    }

At this point you will have 2 domains linked with 2 diferent databases once u click for example:

each tenant (client) has his own database.



4- Install multi-tenant-spring-security plugin and follow this steps(note i didnt implemented the security plugin yet once i do i will post the results):

In Config.groovy, your tenant resolver property should look like this:

tenant{ 
 resolver.type = "springSecurity"
}



You will also need to add the following field to your Spring-Security User Domain Class

Integer userTenantId



Final Issues -->

Every time we fire up grails he will only do a create/update on the default database all the others will remain clean since i still dont know how to solve this problem so i simple exported the default database structure to all my other tenants database.

Finally i didnt do the @MultiTenant Annoation on the domains because i'm working with diferent database didnt saw the point of injecting the tenantid since every db has his own personal records.