Logout Grails Spring安全Rest注销
我正在使用Grails3.1.4和SpringSecurityREST插件2.0.0.M2来实现一个带有AngularJS的单页应用程序。 登录和验证工作得非常好,但当我调用logout时,会出现404错误 调试时,插件RestLogoutFilter中出现异常:Logout Grails Spring安全Rest注销,logout,grails-3.0,spring-security-rest,Logout,Grails 3.0,Spring Security Rest,我正在使用Grails3.1.4和SpringSecurityREST插件2.0.0.M2来实现一个带有AngularJS的单页应用程序。 登录和验证工作得非常好,但当我调用logout时,会出现404错误 调试时,插件RestLogoutFilter中出现异常: try { log.debug "Trying to remove the token" tokenStorageService.removeToken accessToken.accessToken } catch
try {
log.debug "Trying to remove the token"
tokenStorageService.removeToken accessToken.accessToken
} catch (TokenNotFoundException tnfe) {
servletResponse.sendError HttpServletResponse.SC_NOT_FOUND, "Token not found"
}
例外情况:
grails.plugin.springsecurity.rest.token.storage.TokenNotFoundException:
Token eyJh... cannot be removed as this is a stateless implementation
召唤
tokenStorageService.loadUserByToken(accessToken.accessToken)
有效,因此令牌肯定在令牌存储中
我的Spring安全配置是
grails.plugin.springsecurity.userLookup.userDomainClassName = 'myapp.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'myapp.UserRole'
grails.plugin.springsecurity.authority.className = 'myapp.Role'
grails.plugin.springsecurity.userLookup.usernamePropertyName='email'
grails.plugin.springsecurity.rest.login.usernamePropertyName='email'
grails.plugin.springsecurity.rest.token.storage.gorm.usernamePropertyName='email'
grails.plugin.springsecurity.rest.logout.endpointUrl = '/api/logout'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/', access: ['permitAll']],
[pattern: '/error', access: ['permitAll']],
[pattern: '/index', access: ['permitAll']],
[pattern: '/index.gsp', access: ['permitAll']],
[pattern: '/shutdown', access: ['permitAll']],
[pattern: '/assets/**', access: ['permitAll']],
[pattern: '/**/js/**', access: ['permitAll']],
[pattern: '/**/css/**', access: ['permitAll']],
[pattern: '/**/images/**', access: ['permitAll']],
[pattern: '/**/favicon.ico', access: ['permitAll']],
[pattern: '/api/logout', access: ['isAuthenticated()']]
]
grails.plugin.springsecurity.filterChain.chainMap = [
[pattern: '/assets/**', filters: 'none'],
[pattern: '/**/js/**', filters: 'none'],
[pattern: '/**/css/**', filters: 'none'],
[pattern: '/**/images/**', filters: 'none'],
[pattern: '/**/favicon.ico', filters: 'none'],
[pattern: '/api/**', filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter']
]
我的配置中是否有错误或其他错误?在提问几分钟后找到了答案 Spring Security Rest声明: 使用JWT令牌(默认策略)时无法注销,因为服务器中不保留任何状态。如果仍然希望注销,可以通过创建JwtTokenStorageService的子类并重写storeToken和removeToken方法来提供自己的实现。 然后,在resources.groovy中将您的实现注册为tokenStorageService 然而,更合理的方法是从客户端(例如浏览器的本地存储)移除令牌,让令牌过期(它们无论如何都会过期,不像其他存储,如Memcached或Redis,每次访问时都会刷新)
因此,如果使用JWT进行授权,只需删除客户端上的令牌就足够了。您是否有任何教程介绍如何实现第一个建议;“如果您仍然希望注销,可以通过创建JwtTokenStorageService的子类并重写storeToken和removeToken方法来提供自己的实现。然后,在resources.groovy中将您的实现注册为tokenStorageService。”不,我没有,但基本思想很简单。您可以创建一个类似于
CustomJwtTokenStorageService
的类,并从JwtTokenStorageService
派生它。然后实现一些存储和删除机制,并在resources.groovy中注册新服务,如下所述。需要了解的重要一点是,JWT令牌实际上并没有保存在服务器上,因此不需要以这种方式实现注销机制,在客户端上删除令牌就足够了。