我花了很多时间在这个问题上寻求帮助,但没有。在我的grails-2.3.0.RC1应用程序中安装spring安全性插件后,我不断收到此错误。
这是我使用的代码。我没有修改生成的模板,除了创建一个控制器并添加@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但不知道如何在这里做到这一点。任何帮助将不胜感激。
答案 0 :(得分: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"
}
您可以在此处查看为此问题打开的jira http://jira.grails.org/browse/GRAILS-10301
希望这可以帮助任何有类似问题的人。