简体   繁体   English

Grails Spring Security插件-Grails-2.3.0.RC1中的“无法在空对象上调用isLoggedIn()”错误

[英]Grails Spring Security plugin - “Cannot invoke isLoggedIn() on null object” error in grails-2.3.0.RC1

I have spent a lot of time searching for help on this issue but none. 我花了很多时间在这个问题上寻求帮助,但是没有一个。 I am constantly getting this error after i install spring security plugin in my grails-2.3.0.RC1 app. 在grails-2.3.0.RC1应用中安装spring安全插件后,我不断收到此错误。

Here's the the code i used. 这是我使用的代码。 I have not modified the generated templates except create a controller and add @Secured(['ROLE_ADMIN']) to it. 除了创建控制器并向其添加@Secured(['ROLE_ADMIN'])外,我没有修改生成的模板。

The login controller 登录控制器

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)
    }
}

Here's the bootstrap file: 这是引导文件:

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 = {
       }
   }

And the secured controller: 和安全的控制器:

package springsecurity

import grails.plugins.springsecurity.Secured


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

    def index() {

    }
}

And heres the error message when i try to access the controller: 当我尝试访问控制器时,这是错误消息:

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)

Am able to attach the testapp but don't know how to do that here. 能够附加testapp,但是在这里不知道该怎么做。 Any help would be appreciated. 任何帮助,将不胜感激。

Obviously, this problem is related to an issue with grails-2.3.0.RC1 not injecting service bean for plugins correctly. 显然,此问题与grails-2.3.0.RC1没有为插件正确注入服务bean有关。

I was able to fix my problem by adding this to grails-app/conf/resources.groovy 通过将其添加到grails-app / conf / resources.groovy,我能够解决我的问题

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

This makes grails to inject the service first before anything. 这使grails首先要先注入服务。 If you have similar problems using grails-2.3.0RC1, you can add an alias to the resources.groovy file to fix this error. 如果在使用grails-2.3.0RC1时遇到类似的问题,则可以将别名添加到resources.groovy文件中以解决此错误。 For example: 例如:

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

You can see the jira that was opened for this problem here http://jira.grails.org/browse/GRAILS-10301 您可以在http://jira.grails.org/browse/GRAILS-10301处看到针对此问题打开的jira

Hope this helps anyone with similar issues. 希望这对遇到类似问题的人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM