2016-02-23 102 views
2

我的grails 2.5.0應用程序使用Spring Security與ldap和cas插件。我相信這個CAS服務器,所以我需要允許沒有本地(用戶,角色,UserRole表)記錄的用戶進行身份驗證。grails spring security CAS:無法登錄與非本地用戶合作

如果我有本地用戶,一切都很好。如果我沒有本地用戶,那麼我會得到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工作正常,如果用戶是在我的本地數據庫,否則失敗。我錯過了什麼?謝謝。

+0

我使用標準的s2-quickstart創建的類:用戶,角色和UserRole。我確實有一些使用本地角色的用戶。同樣使用ldap,但對於經CAS認證的本地用戶,ldap工作得很好。 在我的代碼中,如果local-db查找失敗,我創建並從CAS票據返回一個新的GrailsUser,但這是我得到錯誤的地方。 – Neal

回答

0

我的問題的答案是微不足道的。將正確數量的參數傳遞給構造函數總是一個好主意。相反的:

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

我只是需要:

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

而且我的用戶是設置爲主體!