我正在使用Grails多租户插件和单租户模式。我使用了spring security core插件进行身份验证。我使用过域名解析器。用户表在默认数据库中不常见。每个租户db都有自己的用户表。它工作正常,但有以下两个问题。
当客户端(租户)用户尝试登录时,有时它会访问默认数据库并说“找不到用户”。如果我在刷新页面后尝试(输入网址并按CTRL + F5),则会正确登录。
我有一个跨租户的普通用户,具有不同的访问权限。首先,我在带有一个租户URL的浏览器中打开我的应用程序,使用凭据登录并成功记录。接下来,我在同一浏览器中打开另一个选项卡,输入第二个URL和登录凭据。在这里,我可以登录到应用程序,但我获得了第一个租户的权限。如果我按照提到的那样注销并刷新页面,或者如果我在登录前刷新页面并尝试,它就可以正常工作。
当我调试时,我发现在解析租户之前,spring安全性会使用之前的db会话攻击数据库。
我该如何解决这个问题?
答案 0 :(得分:1)
当请求到达我的登录页面时,我获得了tenantId并将其保留在会话中
Integer tenantId = tenantResolver?.getTenantFromRequest(request)
if (session.tenantId == null) {
session.tenantId = tenantId
}
要获取登录的用户详细信息,我通过实现GrailsUserDetailsService并在事务中调用来覆盖'loadUserByUsername'方法。
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)
}
}
}
现在我的问题已经解决了。
答案 1 :(得分:0)
您必须确保在Spring安全筛选器之前注册了多租户servlet筛选器。如果不重新编译插件,我不知道如何做到这一点。