0

この問題に関するヘルプを探すのに多くの時間を費やしましたが、何もありません。grails-2.3.0.RC1 アプリに spring security プラグインをインストールした後、常にこのエラーが発生します。

これが私が使用したコードです。コントローラーを作成して @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"
}

この問題のために公開されたジラは、 http: //jira.grails.org/browse/GRAILS-10301 で確認できます。

これが同様の問題を抱えている人に役立つことを願っています。

于 2013-08-22T19:19:05.443 に答える