Почему я не могу войти с помощью Spring Security и плагина Weceem, установленного в Grails Framework 1.3.7 - PullRequest
1 голос
/ 14 июня 2011

Я работаю над почти чистым проектом grails 1.3.7 с установленным weceem 1.0RC2, spring-security-core 1.1.3, spring-security-ui 0.1.2, weceem-spring-security 1.0 и их зависимостями.

Все отлично работает, кроме входа пользователя.Когда я хочу войти через http://localhost:8080/appname/login, я получаю только следующее сообщение об ошибке:

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

Но пользователь все еще существует в базе данных, и я получаю то же сообщение об ошибке, если я использую созданный пользователемSpring-Security-UI.Для кодирования паролей я использую springSecurityService.encodePassword («пароль»).LoginController был сгенерирован Spring-Security (s2-quickstart).

Я думаю, что может быть проблема с Weceem - мост Spring-Security, каково ваше мнение?

С уважением, 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)
}
}

Ответы [ 2 ]

1 голос
/ 21 июля 2011

Я только что решил проблему с идентичными симптомами.

Оказалось, что замыкание сопоставления, которое было в моем Config.groovy, имело опечатку, и я отображал поле, которое не существовало, на 'поле пароля в представлении weceem пользователя.

Таким образом, пользовательский UserDetailsService, внедренный плагином, просто ненавидел моих пользовательских объектов, и ничего не работало правильно.

Я изменилpasswd к паролю на стороне домена сопоставления, чтобы он соответствовал тому, что было на самом деле в моем объекте User, и все было правильно с миром.

0 голосов
/ 14 июня 2011

Сложно сказать по небольшой информации, которую вы предоставили. Плагин Weceem Spring Security соединяет Spring Security Core с механизмом аутентификации Weceem.

Это достигается путем предоставления пользовательской реализации UserDetailsService, которая отображается из класса домена в объект данных сеанса, используемый Spring Security Core.

Этот URL для входа в систему, он сопоставлен с вашим собственным контроллером входа, как описано выше? UserDetailsService в плагине weceem-spring-security использует настроенный класс домена пользователя для вызова findByUsername (username):

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

...