0

我花了很多时间在这个问题上寻求帮助,但没有。在我的 grails-2.3.0.RC1 应用程序中安装 spring 安全插件后,我经常收到此错误。

这是我使用的代码。除了创建一个控制器并将@Secured(['ROLE_ADMIN']) 添加到它之外,我没有修改生成的模板。

登录控制器

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
import grails.plugins.springsecurity.SpringSecurityService
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 = g.message(code: "springSecurity.errors.login.expired")
            }
            else if (exception instanceof CredentialsExpiredException) {
                msg = g.message(code: "springSecurity.errors.login.passwordExpired")
            }
            else if (exception instanceof DisabledException) {
                msg = g.message(code: "springSecurity.errors.login.disabled")
            }
            else if (exception instanceof LockedException) {
                msg = g.message(code: "springSecurity.errors.login.locked")
            }
            else {
                msg = g.message(code: "springSecurity.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)
    }
}

这是引导文件:

import com.security.*

   class BootStrap {

       def init = { servletContext ->
        def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true) 
        def userRole = new Role(authority: 'ROLE_USER').save(flush: true)

        def testUser = new User(username:'emman', enabled: true, password: 'password') 
        testUser.save(flush: true)
        UserRole.create testUser, adminRole, true

       }
       def destroy = {
       }
   }

和安全控制器:

package springsecurity

import grails.plugins.springsecurity.Secured


@Secured(['ROLE_ADMIN'])
class HomeController {

    def index() {

    }
}

当我尝试访问控制器时,这是错误消息:

NullPointerException occurred when processing request: [GET] /springsecurity/login/auth;jsessionid=CABE1DB8CD4C6689CD137F51DBEE85CD
Cannot invoke method isLoggedIn() on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method isLoggedIn() on null object
        at LoginController$_closure2.doCall(LoginController.groovy:46)
        at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
        at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:722)

我能够附加 testapp 但不知道如何在此处执行此操作。任何帮助,将不胜感激。

4

1 回答 1

0

显然,这个问题与 grails-2.3.0.RC1 没有为插件正确注入服务 bean 的问题有关。

我可以通过将其添加到 grails-app/conf/resources.groovy 来解决我的问题

beans = {
    springConfig.addAlias "springSecurityService", "springSecurityCoreSpringSecurityService"
}

这使得 grails 先注入服务。如果您在使用 grails-2.3.0RC1 时遇到类似问题,可以在 resources.groovy 文件中添加别名来修复此错误。例如:

beans={
   springConfig.addAlias "serviceName","pluginNameServiceName"
}

您可以在此处查看针对此问题打开的 jira http://jira.grails.org/browse/GRAILS-10301

希望这可以帮助任何有类似问题的人。

于 2013-08-22T19:19:05.443 回答