2011-06-14 22 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