我試圖安全使用shiro插件的grails應用程序。我有一個簡單的身份驗證系統,可以在開發模式下使用簡單的app-run
。但是,一旦我運行在生產模式(grails prod run-app --stacktrace
)應用程序的任何企圖登錄或註冊拋出下面的錯誤,並拒絕功能:Shiro爆炸與數據庫會話啓用
| 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()
}
}
}
}
嗯。看來你在這個數據庫事務插件不能堅持到數據庫的會話中存儲事端。 檢查會話並確保所有對象都可以被序列化... – rdmueller
我沒有看到任何問題嗎?我添加了一些代碼片段,可能會提供信息 –