【问题标题】:Grails Security: how to preprocess username (to make it case-insensitive)?Grails Security:如何预处理用户名(使其不区分大小写)?
【发布时间】:2013-10-25 07:47:02
【问题描述】:

Spring Security 的默认实现将用户名视为区分大小写,出于可用性原因,我需要使其不区分大小写(一个主要原因是使用移动设备的用户的默认行为是将输入文本的第一个字母大写)。这是业务需求。

当控制权传递给插件生成的 LoginController 时,为时已晚:Spring Security 已经确定登录失败。使用调试器,我可以看到流程通过org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication,但我不知道如何从 Grails 进行干预。其实插件使用了一个子类org.codehaus.groovy.grails.plugins.springsecurity.RequestHolderAuthenticationFilter,不过那是在插件源里面,不是我的应用,所以不知道从哪里干预。

任何指针表示赞赏。 谢谢。

环境:Grails 2.3、Spring Security Plugin 1.2.7.3

【问题讨论】:

    标签: grails spring-security grails-plugin


    【解决方案1】:

    您可以使用自定义 UserDetailsService 执行此操作 - 请参阅 https://grails-plugins.github.io/grails-spring-security-core/v3/index.html#userDetailsService

    package com.yourcompany.yourapp
    
    import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser
    import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService
    import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
    import org.springframework.security.core.authority.GrantedAuthorityImpl
    import org.springframework.security.core.userdetails.UserDetails
    import org.springframework.security.core.userdetails.UsernameNotFoundException
    
    class MyUserDetailsService implements GrailsUserDetailsService {
    
       static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
    
       UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
          User.withTransaction { status ->
             User user = User.findByUsernameIlike(username)
             if (!user) throw new UsernameNotFoundException('User not found', username)
    
             def authorities = user.authorities.collect { new GrantedAuthorityImpl(it.authority) }
    
             new GrailsUser(user.username, user.password, user.enabled, !user.accountExpired, !user.passwordExpired,
                !user.accountLocked, authorities ?: NO_ROLES, user.id)
          }
       }
    
       UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException {
          loadUserByUsername username
       }
    }
    

    在 grails-app/conf/spring/resources.groovy 中注册以覆盖插件的实现:

    beans = {
       userDetailsService(com.yourcompany.yourapp.MyUserDetailsService)
    }
    

    【讨论】:

    • 谢谢。我扩展了 GormUserDetailsS​​ervice 并覆盖了 loadUserByUsername(username) 以调用 super.loadUserByUsername(username.toLowerCase()) 并且它这样做了。令人惊讶的是,它在 org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsS​​ervice#loadUserByUsername 行中失败了:def dc = grailsApplication.getDomainClass(userClassName) with org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: DUMMY.groovy : 1: 意外令牌: = @ line 1, column 64. Closure JETGROOVY_EVAL = {->= grailsAp ^ 1 error 我很困惑...
    • 之前的异常出现在调试器中。在服务器日志中只有 java.lang.NullPointerException: Cannot invoke method getDomainClass() on null object at org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsS​​ervice.loadUserByUsername(GormUserDetailsS​​ervice.groovy:52) at my.app.UserDetailsS​​ervice org.codehaus.groovy.grails.plugins.springsecurity.GormUserDetailsS​​ervice.loadUserByUsername(GormUserDetailsS​​ervice.groovy:77) 上的 .loadUserByUsername(UserDetailsS​​ervice.groovy) 很奇怪,因为 userClassName 正确设置为“my.app.SpringUser”(和以前一样)
    • 已经在 Config.groovy 中定义了属性:grails.plugins.springsecurity.userLookup.userDomainClassName = 'my.appSpringUser' grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'my.appSpringUserRole' grails.plugins.springsecurity.authority.className = 'my.appRole'
    • 嗯..发现userDetailsService(com.yourcompany.yourapp.MyUserDetailsService)导致grailsApplication没有被注入。但是,当然也不会调用自定义服务。
    • 尝试我的答案中的版本,更新为使用您的域类。它比插件简单得多,插件非常复杂,因为它支持自定义类和属性名称。但是当你自己做的时候,只使用你真正的类就干净多了。如果你想子类化插件的 impl,像这样注册它:beans = { userDetailsService(com.yourcompany.yourapp.MyUserDetailsService) { grailsApplication = ref('grailsApplication') } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    相关资源
    最近更新 更多