2

shiro プラグインを使用して grails アプリケーションを保護しようとしています。app-runシンプルな開発モードで正常に動作するシンプルな認証システムを用意しています。ただし、プロダクション モードでアプリケーションを実行すると ( grails prod run-app --stacktrace)、ログインまたは登録しようとすると、以下のエラーがスローされ、機能しなくなります。

| Error 2012-12-03 05:35:15,081 [http-bio-8080-exec-9] ERROR databasesession.GormPersisterService  - [Assertion failed] - this String argument must have length; it must not be null or empty
Message: [Assertion failed] - this String argument must have length; it must not be null or empty
   Line | Method
->>  45 | deleteBySessionId in grails.plugin.databasesession.PersistentSessionAttributeValue
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   111 | invalidate        in grails.plugin.databasesession.GormPersisterService
|    90 | proxySession . .  in grails.plugin.databasesession.SessionProxyFilter
|    42 | getSession        in grails.plugin.databasesession.SessionProxyFilter$1
|   147 | getSession . . .  in org.apache.shiro.web.servlet.ShiroHttpServletRequest
|   188 | getSession        in     ''
|   108 | createSession . . in org.apache.shiro.web.session.mgt.ServletContainerSessionManager
|    64 | start             in     ''
|   121 | start . . . . . . in org.apache.shiro.mgt.SessionsSecurityManager
|   336 | getSession        in org.apache.shiro.subject.support.DelegatingSubject
|   314 | getSession . . .  in     ''
|   182 | mergePrincipals   in org.apache.shiro.mgt.DefaultSubjectDAO
|   163 | saveToSession . . in     ''
|   144 | save              in     ''
|   383 | save . . . . . .  in org.apache.shiro.mgt.DefaultSecurityManager
|   350 | createSubject     in     ''
|   183 | createSubject . . in     ''
|   283 | login             in     ''
|   257 | login . . . . . . in org.apache.shiro.subject.support.DelegatingSubject
|    68 | register          in pfm.SignupController
|   195 | doFilter . . . .  in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|    63 | doFilter          in grails.plugin.cache.web.filter.AbstractFilter
|    55 | doFilter . . . .  in org.apache.shiro.grails.SavedRequestFilter
|   449 | executeChain      in org.apache.shiro.web.servlet.AbstractShiroFilter
|   365 | call . . . . . .  in org.apache.shiro.web.servlet.AbstractShiroFilter$1
|    90 | doCall            in org.apache.shiro.subject.support.SubjectCallable
|    83 | call . . . . . .  in     ''
|   380 | execute           in org.apache.shiro.subject.support.DelegatingSubject
|   362 | doFilterInternal  in org.apache.shiro.web.servlet.AbstractShiroFilter
|   125 | doFilter          in org.apache.shiro.web.servlet.OncePerRequestFilter
|    51 | doFilterInternal  in grails.plugin.databasesession.SessionProxyFilter
|   886 | runTask           in java.util.concurrent.ThreadPoolExecutor$Worker
|   908 | run . . . . . . . in     ''
^   680 | run               in java.lang.Thread

開発モードではデータベースセッションが無効になっており、スタックトレースに含まれdatabasesessionているため、そこに問題があると思います。何が原因で、どのように修正するのかわかりません。

役立つかもしれないいくつかの仕様:

Grails 2.1.1
compile ":shiro:1.1.4"

詳細情報を提供できる場合はお知らせください。事前に感謝します

更新:認証コントローラーで、それをトリガーするコードは次のとおりです。

  def signIn = {
        def authToken = new UsernamePasswordToken(params.username, params.password as String)

        // Support for "remember me"
        if (params.rememberMe) {
            authToken.rememberMe = true
        }

        // If a controller redirected to this page, redirect back
        // to it. Otherwise redirect to the root URI.
        def targetUri = params.targetUri ?: "/"

        // Handle requests saved by Shiro filters.
        def savedRequest = WebUtils.getSavedRequest(request)
        if (savedRequest) {
            targetUri = savedRequest.requestURI - request.contextPath
            if (savedRequest.queryString) targetUri = targetUri + '?' + savedRequest.queryString
        }

        try{
            // Perform the actual login. An AuthenticationException
            // will be thrown if the username is unrecognised or the
            // password is incorrect.
            SecurityUtils.subject.login(authToken)

            log.info "Redirecting to '${targetUri}'."
            redirect(uri: targetUri)
        }
        catch (AuthenticationException ex){
            // Authentication failed, so display the appropriate message
            // on the login page.
            log.info "Authentication failure for user '${params.username}'."
            flash.message = message(code: "login.failed")

            // Keep the username and "remember me" setting so that the
            // user doesn't have to enter them again.
            def m = [ username: params.username ]
            if (params.rememberMe) {
                m["rememberMe"] = true
            }

            // Remember the target URI too.
            if (params.targetUri) {
                m["targetUri"] = params.targetUri
            }

            // Now redirect back to the login page.
            redirect(action: "login", params: m)
        }
    }

関連するドメイン クラス:

class User {
    String username
    String passwordHash
    byte[] passwordSalt
    Manager manager

    static hasMany = [ roles: Role, permissions: String ]

    static constraints = {
        username(nullable: false, blank: false, unique: true)
        manager(nullable: true)
    }
}

そして最後にセキュリティ フィルター:

class SecurityFilters {

    def publicActions = [
        signup: ['index','register'],
        auth:['*','*']
    ]

    private boolean findAction(controllerName, actionName){
        def c = publicActions[controllerName]
        return(c)?c.find{(it==actionName||it=='*')}!=null:false
    }

    def filters = {

        all(uri: "/**"){
            before = {
                //Check for public controller/actions
                def isPublic=findAction(controllerName,actionName)

                if(isPublic) return true

                // Ignore direct views (e.g. the default main index page).
                if (!controllerName) return true

                accessControl()
            }
        }
    }
}
4

1 に答える 1

1

うーん。データベースセッションプラグインのソースを見てみました。例外の行番号をソースと一致させることができません。どのバージョンのプラグインを使用していますか?

私にとっては、データベース セッション プラグインが sessionId を見逃しており、無効なセッション ID でセッションを無効にしようとしているようです。

私にとっては、プラグインの V1.12 でバグに遭遇したようです: http://jira.grails.org/browse/GPDATABASESESSION-1

これはすでに修正されているようですが、grails.org ではリリースされていません。

最新バージョンを入手するには、https://github.com/burtbeckwith/grails-database-session/archive/master.zipからダウンロードして解凍し、ディレクトリの名前を に変更しgrails-database-sessionます。

シェルを開き、cd でgrails-database-sessionディレクトリに移動します。を実行しgrails package-pluginます。Grails のバージョンが間違っているというエラーが表示された場合は、正しいバージョンに切り替えるかgrails upgrade、何度もgrails package-pluginやり直してください。

プロジェクトに cd して、grails install-plugin /path/to/grails-database-session/grails-database-session-1.2.zip.

少なくとも、これは私にとってはうまくいきました...

于 2012-12-04T08:46:59.853 に答える