grails - Shiro 因启用数据库 session 而崩溃

标签 grails shiro

我正在尝试使用 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

由于数据库 session 在开发模式下被禁用并且堆栈跟踪包含 databasesession我假设这就是问题所在。我不知道是什么原因造成的,也不知道如何解决。

一些可能有用的规范:
Grails 2.1.1
compile ":shiro:1.1.4"

让我知道我是否可以提供更多信息并提前致谢

更新:
这是在身份验证 Controller 中触发它的代码:
  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()
            }
        }
    }
}

最佳答案

嗯。刚刚看了一下数据库 session 插件的来源。我无法将您的异常的行号与源匹配。您使用的是哪个版本的插件?

对我来说,看起来数据库 session 插件错过了一个 sessionId 并试图用无效的 session ID 使 session 无效。

对我来说,您似乎偶然发现了插件 V1.12 中的一个错误:http://jira.grails.org/browse/GPDATABASESESSION-1

这似乎已经修复但未在 grails.org 上发布。

要获取最新版本,请从 https://github.com/burtbeckwith/grails-database-session/archive/master.zip 下载,解压并重命名目录为grails-database-session .

打开 shell 并 cd 进入 grails-database-session目录。执行 grails package-plugin .如果它提示 grails 版本错误,要么切换到正确的版本,要么执行 grails upgradegrails package-plugin再次。

现在 cd 到您的项目并执行 grails install-plugin /path/to/grails-database-session/grails-database-session-1.2.zip .

至少,这对我有用......

关于grails - Shiro 因启用数据库 session 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13684634/

相关文章:

java - Netbeans 8.0.1 找不到 shiro.ini

java - Apache ·希罗. WebUtils.isWeb(...) 和 WebUtils.isHttp(...) 有什么区别?

grails - 如何在Grails中为字符串列表构建编辑表单?

java - 在PDF的每一页附加水印图像

spring - 装饰 Grails 提供的 Spring bean

java - HttpResponse 中的状态代码错误

authentication - Grails 应用程序中的安全性 : Acegi or Shiro

java - Fuseki 服务器不显示数据集

grails - Grails-无法解决依赖关系

grails - 创建和删除服务后 jar 和 grails 之间的奇怪 Grails 类型解析