Grails,Spring Security Rest插件,无法在空对象上调用方法loadUserByToken()

Xixin He

我正在尝试在grails framework(2.5.0)中使用Spring Security Plugin(2.0.0)和Spring Authentication Rest Plugin(1.5.3)实现基于令牌的身份验证。我将标头字段“ x-auth-token”设置为令牌,并将其发布到目标控制器URL。但是,IDE(Intellij IDEA)弹出此错误消息

| Error 2016-07-12 15:58:27,864 [http-bio-8080-exec-10] ERROR [/hello_world].
[default]  - Servlet.service() for servlet [default] in context with path [/hello_world] threw exception
Message: Cannot invoke method loadUserByToken() on null object
Line | Method
->>   55 | authenticate in grails.plugin.springsecurity.rest.RestAuthenticationProvider
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|     75 | doFilter     in grails.plugin.springsecurity.rest.RestTokenValidationFilter
|     53 | doFilter . . in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
|    143 | doFilter     in grails.plugin.springsecurity.rest.RestAuthenticationFilter
|     62 | doFilter . . in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
|     80 | doFilter     in grails.plugin.springsecurity.rest.RestLogoutFilter
|     59 | doFilter . . in grails.plugin.springsecurity.web.SecurityRequestHolderFilter
|     82 | doFilter     in com.brandseye.cors.CorsFilter
|   1142 | runWorker .  in java.util.concurrent.ThreadPoolExecutor
|    617 | run          in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run . . . .  in java.lang.Thread

我检查了此loadUserByToken()方法,并在tokenStorageService上调用了它。我不知道为什么这个tokenStorageService是空对象。Spring Security和Spring Security插件的配置如下:

Config.groovy

// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'hello_world.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'hello_world.UserRole'
grails.plugin.springsecurity.authority.className = 'hello_world.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
    '/':                ['permitAll'],
    '/index':           ['permitAll'],
    '/index.gsp':       ['permitAll'],
    '/assets/**':       ['permitAll'],
    '/**/js/**':        ['permitAll'],
    '/**/css/**':       ['permitAll'],
    '/**/images/**':    ['permitAll'],
    '/**/favicon.ico':  ['permitAll'],
    '/api/login':       ['permitAll']
]

grails {
    plugin {
        springsecurity {

            filterChain.chainMap = [
                    '/api/guest/**': 'anonymousAuthenticationFilter,restTokenValidationFilter,restExceptionTranslationFilter,filterInvocationInterceptor',
                    '/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter',  // Stateless chain
                    '/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'                                                                          // Traditional chain
            ]

            providerNames = ['restAuthenticationProvider','daoAuthenticationProvider', 'rememberMeAuthenticationProvider']

            auth.loginFormUrl = '/login/auth'

            useSecurityEventListener = true

            onAuthenticationSuccessEvent = { e, appCtx ->
                // handle AuthenticationSuccessEvent

                System.out.println("Authentication Succeeded");
            }

            onAuthenticationSwitchUserEvent = { e, appCtx ->
                // handle AuthenticationSwitchUserEvent
            }

            onAuthorizationEvent = { e, appCtx ->
                // handle AuthorizationEvent
            }

            onRestTokenCreationEvent = { e, appCtx ->

                System.out.println("Token Created")
            }

            apf {
                filterProcessesUrl = '/api/login'
                allowSessionCreation = false
//                usernamePropertyName = 'username'
//                passwordPropertyName = 'password'
            }

            rest {

                active = true

                login {
                    active = true
                    endpointUrl = '/api/login'
                    failureStatusCode = 401
                    useJsonCredentials = true
                    usernamePropertyName = 'username'
                    passwordPropertyName = 'password'
                }

                token {

                    validation {
                        active = true
                        endpointUrl = '/api/validate'
                        headerName = 'x-auth-token'
                        useBearerToken = false
                        tokenPropertyName = 'access_token'
                        enableAnonymousAccess = true
                    }

                    generation {
                        active = true
                        useSecureRandom = true
                        useUUID = false
                    }

                    rendering {
                        usernamePropertyName = 'username'
                        authoritiesPropertyName = 'roles'
                        tokenPropertyName = 'token'
                    }

                    storage {
                        active = true
                        useGorm = true

                        gorm {
                            tokenDomainClassName = 'hello_world.AuthenticationToken'
                            tokenValuePropertyName = 'tokenValue'
                            usernamePropertyName = 'username'
                        }
                    }
                }
            }
        }
    }
}

resources.groovy

import grails.plugin.springsecurity.rest.RestAuthenticationProvider
beans = {
    restAuthenticationProvider(RestAuthenticationProvider);
}

并且我已经检查了数据库,令牌存储在authentication_token表中。我是grails的新手,一直在搜索时间,一点都不知道。谁能帮我?非常感激。

如果您还有其他需要,请告诉我。

Xixin He

经过多次尝试,对于遇到相同问题的人,我终于弄明白了。似乎我不应该在resources.groovy中声明restAuthenticationProvider,也不应该在config.groovy中的grails.plugin.springsecurity.providerNames中添加restAuthenticationProvider。列出了spring-security-core和spring-security-rest的完整配置,如下所示:

config.groovy

grails {
    plugin {
        springsecurity {

            useSecurityEventListener = true

            filterChain {
                chainMap = [
                        '/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter',  // Stateless chain
                        '/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'                                                                          // Traditional chain
                ]
            } //filterChain

            apf {
                filterProcessesUrl = '/api/login'
            } //apf

            rest {

                login {
                    active = true
                    useRequestParamsCredentials = false
                    useJsonCredentials = true
                    usernamePropertyName = 'j_username'
                    passwordPropertyName = 'j_password'
                    endpointUrl = '/api/login'
                } //login

                logout {

                } //logout

                token {

                    validation {
                        active = true
                        endpointUrl = '/api/validate'
                        useBearerToken = false
                        headername = 'X-Auth-Token'
                    } //validation

                    generation {
//                        active = true
//                        useSecureRandom = true;
//                        useUUID = false;
                    }

                    rendering {
                        usernamePropertyName = 'username'
                        authoritiesPropertyName = 'roles'
                        tokenPropertyName = 'token'
                    }

                    storage {
//                        useJWT = true;
                    } //storage
                } //token
            } //rest

            cors.headers = ['Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Auth-Token']
        } //springsecurity
    } //plugin
} //grails

您应该以json格式发送用户名和密码,并使用字段“ j_username”和“ j_password”,它将返回json格式的令牌。然后,将请求以及此令牌在标头字段“ X-Auth-Token”中发送到您要查询的api。

要初始化spring-security-core插件,请参阅http://grails-plugins.github.io/grails-spring-security-core/v2/guide/single.html#tutorials

github上提供了我的完整代码:https//github.com/xixinhe/api_token_authentication

在运行我的代码之前,请安装oracle mysql 5。

如果有任何我写的违反堆栈溢出规则的内容,请告诉我,我将进行更改。

我不是英语母语人士,请原谅我粗俗的英语。

谢谢,

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Grails Spring Security REST + LDAP

Grails + Spring Security:无法登录

Grails Spring Security插件和dbconsole

Grails Spring Security Core无法登录

404在Grails的Spring Security Rest插件中注销

在Grails应用中使用Spring Security Rest插件调用登录时出现401未经授权的错误

Grails 3 Spring Security LDAP插件和Tomcat 8

Grails Spring Security Facebook插件不起作用

Grails Spring Security插件类的首选软件包

Grails Spring Security插件-登录表单重定向到ajaxAuth

使用Grails Spring Security CAS插件进行重定向循环

Grails Spring Security拒绝访问其他插件

Grails-grails-spring-security-rest-无法从application.yml加载jwt secret

Grails Spring Security 3服务springSecurityService为空

Grails 3:Spring Security Rest 返回登录页面

Grails 3.3.9 Spring Security 3.2.3 Spring Security UI 3.1.2无法更改用户数据

在使用内联 grails 插件运行 grails 应用程序时,无法在空对象异常上调用方法 assetBaseUrl()

在Grails中获取'无法在空对象上调用方法loadUserByUsername()'

Grails Spring Security静态规则

如何在Grails中使用Spring Security Rest插件进行身份验证

添加Spring Security插件3.1.1后将无法加载Grails 3.2.4应用程序

405在/ api / login OPTIONS请求中不允许使用grails-spring-security-rest插件(方法仍在继续...)

ifNotLoggedIn标签-Grails 2.4.4 / Spring Security 2.0-RC4-无法在空对象上获取属性'securityConfig'

Grails Spring Security插件使用配置类型注释设置匿名访问

使用Spring Security Core插件在Grails中登录后如何重定向到页面

Grails Spring Security插件在哪里将currentUser保存在HttpSession中

如何在Grails Spring Security Core插件中自定义凭据检查?

Grails:Spring Security插件对简单安全性功能是否强大

具有多个Active Directory服务器的Grails Spring Security LDAP插件