2011-06-14 64 views
1

我正在與weceem 1.0RC2,spring-security-core 1.1.3,spring -security-ui 0.1.2,weceem-spring-security 1.0及其依賴項。爲什麼我無法登錄彈簧安全和Weceem插件安裝在Grails框架1.3.7

除用戶登錄外,一切正常。當我想登陸過http://localhost:8080/appname/login我只得到了以下錯誤消息:

Sorry, we were not able to find a user with that username and password. 

但用戶仍然存在於數據庫中,我也得到了同樣的錯誤消息,如果我用彈簧安全的UI創建了一個用戶。編碼密碼我使用springSecurityService.encodePassword('密碼')。 LoginController由spring-security(s2-quickstart)生成。

我認爲weceem - spring-security bridge可能存在問題,您的看法如何?

最好的問候, whitenexx

import grails.converters.JSON 
import javax.servlet.http.HttpServletResponse 
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils 
import org.springframework.security.authentication.AccountExpiredException 
import org.springframework.security.authentication.CredentialsExpiredException 
import org.springframework.security.authentication.DisabledException 
import org.springframework.security.authentication.LockedException 
import org.springframework.security.core.context.SecurityContextHolder as SCH 
import org.springframework.security.web.WebAttributes 
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter 

class LoginController { 

/** 
* Dependency injection for the authenticationTrustResolver. 
*/ 
def authenticationTrustResolver 

/** 
* Dependency injection for the springSecurityService. 
*/ 
def springSecurityService 

/** 
* Default action; redirects to 'defaultTargetUrl' if logged in, /login/auth otherwise. 
*/ 
def index = { 
    if (springSecurityService.isLoggedIn()) { 
     redirect uri: SpringSecurityUtils.securityConfig.successHandler.defaultTargetUrl 
    } 
    else { 
     redirect action: auth, params: params 
    } 
} 

/** 
* Show the login page. 
*/ 
def auth = { 

    def config = SpringSecurityUtils.securityConfig 

    if (springSecurityService.isLoggedIn()) { 
     redirect uri: config.successHandler.defaultTargetUrl 
     return 
    } 

    String view = 'auth' 
    String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}" 
    render view: view, model: [postUrl: postUrl, 
       rememberMeParameter: config.rememberMe.parameter] 
} 

/** 
* The redirect action for Ajax requests. 
*/ 
def authAjax = { 
    response.setHeader 'Location', SpringSecurityUtils.securityConfig.auth.ajaxLoginFormUrl 
    response.sendError HttpServletResponse.SC_UNAUTHORIZED 
} 

/** 
* Show denied page. 
*/ 
def denied = { 
    if (springSecurityService.isLoggedIn() && 
    authenticationTrustResolver.isRememberMe(SCH.context?.authentication)) { 
     // have cookie but the page is guarded with IS_AUTHENTICATED_FULLY 
     redirect action: full, params: params 
    } 
} 

/** 
* Login page for users with a remember-me cookie but accessing a IS_AUTHENTICATED_FULLY page. 
*/ 
def full = { 
    def config = SpringSecurityUtils.securityConfig 
    render view: 'auth', params: params, 
      model: [hasCookie: authenticationTrustResolver.isRememberMe(SCH.context?.authentication), 
       postUrl: "${request.contextPath}${config.apf.filterProcessesUrl}"] 
} 

/** 
* Callback after a failed login. Redirects to the auth page with a warning message. 
*/ 
def authfail = { 

    def username = session[UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY] 
    String msg = '' 
    def exception = session[WebAttributes.AUTHENTICATION_EXCEPTION] 
    if (exception) { 
     if (exception instanceof AccountExpiredException) { 
      msg = SpringSecurityUtils.securityConfig.errors.login.expired 
     } 
     else if (exception instanceof CredentialsExpiredException) { 
      msg = SpringSecurityUtils.securityConfig.errors.login.passwordExpired 
     } 
     else if (exception instanceof DisabledException) { 
      msg = SpringSecurityUtils.securityConfig.errors.login.disabled 
     } 
     else if (exception instanceof LockedException) { 
      msg = SpringSecurityUtils.securityConfig.errors.login.locked 
     } 
     else { 
      msg = SpringSecurityUtils.securityConfig.errors.login.fail 
     } 
    } 

    if (springSecurityService.isAjax(request)) { 
     render([error: msg] as JSON) 
    } 
    else { 
     flash.message = msg 
     redirect action: auth, params: params 
    } 
} 

/** 
* The Ajax success redirect url. 
*/ 
def ajaxSuccess = { 
    render([success: true, username: springSecurityService.authentication.name] as JSON) 
} 

/** 
* The Ajax denied redirect url. 
*/ 
def ajaxDenied = { 
    render([error: 'access denied'] as JSON) 
} 
} 
+0

我記錄了mysql查詢,發現這個:select this_.id as id9_0_,this_.version as version9_0_,this_.account_expired as account3_9_0_,this_.account_locked as account4_9_0_,this_.enabled as enabled9_0_,this_.password' as password6_9_0_ ,this_.password_expired爲password7_9_0_,this_。用戶名爲username9_0_ from user this_ where this_.username ='admin'----->我認爲有錯誤? – whitenexx 2011-10-08 17:48:17

回答

0

它有點棘手,從您提供的一點信息,告訴。 Weceem Spring Security插件將Spring Security Core與Weceem的身份驗證機制聯繫起來。

它通過提供一個自定義的UserDetailsS​​ervice實現來實現,該實現從域類映射到Spring Security Core使用的會話數據對象。

此登錄URL是否映射到上面詳細描述的自己的登錄控制器?在weceem彈簧安全插件的UserDetailsS​​ervice使用配置的用戶域類調用findByUsername(用戶名):

void afterPropertiesSet() { 
    def conf = grailsApplication.config 
    def clsname = conf.grails.plugins.springsecurity.userLookup.userDomainClassName 
    domainClass = grailsApplication.getDomainClass(clsname).clazz 

    def mapper = conf.weceem.springsecurity.details.mapper 
    if (!(mapper instanceof Closure)) { 
     throw new IllegalArgumentException(
      "Your Config must specify a closure in weceem.springsecurity.details.mapper "+ 
      "that maps the domain model to a non-domain object, providing at least: ${REQUIRED_MAPPED_FIELDS}") 
    } 
    detailsMapper = mapper 
} 

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 

    domainClass.withTransaction { status -> 

     def user = domainClass.findByUsername(username) 
     if (!user) throw new UsernameNotFoundException('User not found', username) 

...

所以你可以從上面看到的,我覺得最後行可能是它放棄你的地方,由於一些春季域類/用戶名問題?

如果問題與安裝後登錄Weceem有關(它看起來不是這樣),您需要確保您已配置Weceem Spring Security應如何從您的用戶域類映射到需要的內部數據weceem春季秒核心功能,請參閱:

http://grails.org/plugin/weceem-spring-security

+0

閱讀上面的@Dan解決方案,我可能會建議您更改文檔,以便映射關閉中的字段名稱是password:password,而不是password:passwd - 謝謝:) – sbglasius 2011-09-14 21:56:09

+0

也許有人可以通過一些簡短的步驟告訴我如何設置一個Grails 1.3.7應用程序,包含spring security,weceem和spring security weceem插件?我認爲我的錯誤在別處..謝謝! :) – whitenexx 2011-10-08 16:00:36

1

我剛剛解決的問題有相同的症狀。

事實證明,我在Config.groovy中的映射閉包存在拼寫錯誤,而且我正在將不存在的字段映射到用戶weceem視圖中的「密碼」字段。

所以由插件注入的自定義UserDetailsS​​ervice只是討厭我的用戶對象,沒有任何工作正確。

我將passwd更改爲映射的域側的密碼,以使其與我的用戶對象中的實際內容匹配,並且所有內容都與世界一致。

+0

你是我的英雄!謝謝。 – sbglasius 2011-09-14 21:54:57