grails spring security CAS:无法登录与非本地用户

时间:2016-02-23 16:24:39

标签: spring grails cas

我的grails 2.5.0应用程序使用带有ldap和cas插件的Spring Security。我相信这个CAS服务器,所以我需要允许没有本地(User,Role,UserRole表)记录的用户进行身份验证。

如果我有本地用户,一切都很好。如果我没有本地用户,那么我会收到CAS重定向错误,然后是“抱歉,我们无法找到具有该用户名和密码的用户”。我读到CAS提供的GormUserDetailsS​​ervice对非本地用户不起作用,所以我编写了自己的MyUserDetailsS​​ervice来实现GrailsUserDetailsS​​ervice,我在./conf/spring/resources.groovy:

beans = {
    userDetailsService(edu.uga.reg.MyUserDetailsService)
}

不幸的是,这并没有解决问题:它适用于本地用户,但如果用户不在我的本地数据库中,则会给出相同的重定向+用户未找到错误。这是MyUserDetailService代码:

import grails.plugin.springsecurity.SpringSecurityUtils
import grails.plugin.springsecurity.userdetails.GrailsUser
import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService
import grails.transaction.Transactional
import org.springframework.security.core.authority.GrantedAuthorityImpl
import edu.uga.reg.User
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException

class MyUserDetailsService implements GrailsUserDetailsService {

   /**
    * Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least
    * one role, so we give a user with no granted roles this one which gets
    * past that restriction but doesn't grant anything.
    */
   static final List NO_ROLES =
      [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]

   UserDetails loadUserByUsername(String username, boolean loadRoles)
            throws UsernameNotFoundException {
      return loadUserByUsername(username)
   }

   UserDetails loadUserByUsername(String username) {
      def user = User.findByUsername(username)

      // No local user in my db: create one from this username
      if (!user)
          return new GrailsUser(username, '', true, true, true, NO_ROLES, 999)

      def authorities = user.authorities.collect {
         new GrantedAuthorityImpl(it.authority)
      }

      return new GrailsUser(user.username, user.password,
         user.enabled, !user.accountExpired, !user.passwordExpired,
         !user.accountLocked, authorities ?: NO_ROLES, user.id)
   }
}

以下是我在Config.groovy中的cas设置:

grails.plugin.springsecurity.providerNames = ['casAuthenticationProvider']
grails.plugin.springsecurity.useCAS = true
grails.plugin.springsecurity.cas.active = true
grails.plugin.springsecurity.cas.loginUri = '/login'
grails.plugin.springsecurity.cas.serverUrlPrefix = 'https://cas.dev.server/cas'
grails.plugin.springsecurity.cas.serviceUrl = 'https://apps-dev.server:8743/CASIS/j_spring_cas_security_check'
grails.plugin.springsecurity.logout.afterLogoutUrl = 'https://cas.dev.server/cas/logout?url=http://apps-dev.server:8743/CASIS/'

//default cas settings
grails.plugin.springsecurity.cas.sendRenew = false
grails.plugin.springsecurity.cas.key = 'grails-spring-security-cas'
grails.plugin.springsecurity.cas.artifactParameter = 'ticket'
grails.plugin.springsecurity.cas.serviceParameter = 'service'
grails.plugin.springsecurity.cas.filterProcessesUrl = '/j_spring_cas_security_check'
grails.plugin.springsecurity.cas.useSingleSignout = true
grails.plugin.springsecurity.cas.serverUrlEncoding = 'UTF-8'
grails.plugin.springsecurity.cas.proxyCallbackUrl = null
grails.plugin.springsecurity.cas.proxyReceptorUrl = null

同样,如果用户在我的本地数据库中,CAS工作正常,但否则失败。我错过了什么?感谢。

1 个答案:

答案 0 :(得分:0)

我的问题的答案是微不足道的。将正确数量的参数传递给构造函数总是一个好主意。而不是:

return new GrailsUser(username, '', true, true, true, NO_ROLES, 999)

我只需要:

return new GrailsUser(username, '', true, true, true, true, NO_ROLES, 999)

我的用户被设置为校长!