Grails Spring安全覆盖当前用户在多个字段上查找&不只是用户名

时间:2017-06-12 15:58:07

标签: grails spring-security

我们有一个使用Spring Security的Grails Web App和一个具有用户名,电子邮件和全名的User对象。在很多地方我们在处理请求时调用springSecurityService.currentUser - 这当前工作正常,并根据用户名返回用户(以前一直是电子邮件地址,因此是唯一的)

但是,现在需要进行更改,其中用户名可能不是电子邮件,因此在用户对象中不是唯一的 - 它还必须考虑可选的电子邮件和全名字段。这意味着我们可以有两个名为“bobsmith”的用户。只要他们的电子邮件/全名值不同。

据我所知,springSecurity.currentUser只根据用户名对User表进行查找 - 这对我们来说不再适用,因为它可能只检索它找到的第一个匹配的用户名,这可能是错误的。< / p>

是否可以配置Grails / Spring Security以根据多个字段设置当前用户。我确切地知道我想要做什么,这在伪逻辑中是有效的(我知道这是不可能的):

if (email && !fullname) {
            springSecurityService.currentUser = User.findByUsernameAndEmail(username)
        } else if (!email && fullname) {
            springSecurityService.currentUser = User.findByUsernameAndFullname(username, fullname)
        } else if (email && fullname) {
            springSecurityService.currentUser = User.findByUsernameAndEmailAndFullname(username, email, fullname)
        }

SpringSecurityService getCurrentUser()是:

def getCurrentUser() {
        if (!isLoggedIn()) {
            return null
        }

        def User = getClassForName(securityConfig.userLookup.userDomainClassName)

        if (principal instanceof GrailsUser) {
            User.get principal.id
        }
        else {
            User.createCriteria().get {
                String usernamePropertyName = securityConfig.userLookup.usernamePropertyName
                eq usernamePropertyName, principal[usernamePropertyName]
                cache true
            }
        }
    }

最后一部分是我们案例中正在执行的内容:

User.createCriteria().get {
                String usernamePropertyName = securityConfig.userLookup.usernamePropertyName
                eq usernamePropertyName, principal[usernamePropertyName]
                cache true
            }

有没有办法以某种方式更改此功能?我考虑过在链中添加一个自定义过滤器,但不确定这是否会根据修复为username属性的检索逻辑产生任何差异(当然,我不想改变,因为它是正确的)。

非常感谢任何帮助或建议

1 个答案:

答案 0 :(得分:0)

getCurrentUser is a generic helper method that you never have to use (and it is not used by the plugin itself) - it's just there for your convenience. If it doesn't work in your application, don't use it - just create your own utility method with your custom logic.

In cases where your authentication logic is more complex than using the username and password properties, you can register a custom UserDetailsService and use your logic there.

Note that the concept of the 'current user' and the logic used during authentication are typically closely related but not it all cases, so you can make either or both of these changes depending on your needs.