0
votes

I am using Grails multi-tenant plugin with single-tenant mode. I have used spring security core plugin for authentication. I have used domain name resolver. User table is not common in default database. Every tenant db has it's own user tables. It works fine except with the following 2 issues.

  1. When the client(tenant) user tries to login, sometime it hits the default database and say 'User Not found'. If I try after refreshing the page(entering the url and press CTRL+F5), it logins correctly.

  2. I have a common user across the tenants with different access permissions. First I open my application in a browser with one tenant URL, login with the credentials and logged successfully. Next I open another tab in the same browser, enter the second url and login credentials. Here I am able to login to the application but I get the permissions of the 1st tenant. If I logout and refresh the page as mentioned or if I refresh the page before login and try, it works fine.

When I debugged, I found that before resolving the tenant, spring security hits the database with the previous db session.

How can I resolve this?

2

2 Answers

1
votes

When the request hits my login page, I get the tenantId and keep it in the session

Integer tenantId = tenantResolver?.getTenantFromRequest(request)
if (session.tenantId == null) {
   session.tenantId = tenantId
}

To get the logged in user details, I override the 'loadUserByUsername' method by implementing GrailsUserDetailsService and called within the transaction.

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  def requst = SecurityRequestHolder.request
  def httpSession = requst.getSession(false)
  Integer tenant = httpSession.tenantId
  TenantUtils.doWithTenant (tenant) {
 User.withTransaction { status ->
       User user = User.findByUsername(username)
     }
  }
}

Now my issue is solved.

0
votes

You have to make sure that the multi-tenant servlet filter is registered before the Spring security filter. I'm not sure how to do this without recompiling the plugin.