Grails Spring 安全休息注销
Grails Spring Security Rest Logout
我正在使用 Grails 3.1.4 和 Spring Security Rest Plugin 2.0.0.M2 来实现带有 AngularJS 的单页应用程序。
登录和验证工作正常,但是当我调用注销时,出现 404 错误。
调试时,插件RestLogoutFilter出现异常:
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)
有效,因此令牌肯定在 tokenStorage 中。
我的 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 安全休息 plugin documentation 指出:
Logout is not possible when using JWT tokens (the default strategy), as no state is kept in the server. If you still want to have logout, you can provide your own implementation by creating a subclass of JwtTokenStorageService and overriding the methods storeToken and removeToken.
Then, register your implementation in resources.groovy as tokenStorageService.
However, a more rational approach would be just to remove the token from the client (eg, browser's local storage) and let the tokens expire (they will expire anyway, unlike with other storages like Memcached or Redis where they get refreshed on every access).
因此,如果使用 JWT 进行授权,只需删除客户端上的令牌即可。
我正在使用 Grails 3.1.4 和 Spring Security Rest Plugin 2.0.0.M2 来实现带有 AngularJS 的单页应用程序。 登录和验证工作正常,但是当我调用注销时,出现 404 错误。
调试时,插件RestLogoutFilter出现异常:
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)
有效,因此令牌肯定在 tokenStorage 中。
我的 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 安全休息 plugin documentation 指出:
Logout is not possible when using JWT tokens (the default strategy), as no state is kept in the server. If you still want to have logout, you can provide your own implementation by creating a subclass of JwtTokenStorageService and overriding the methods storeToken and removeToken. Then, register your implementation in resources.groovy as tokenStorageService.
However, a more rational approach would be just to remove the token from the client (eg, browser's local storage) and let the tokens expire (they will expire anyway, unlike with other storages like Memcached or Redis where they get refreshed on every access).
因此,如果使用 JWT 进行授权,只需删除客户端上的令牌即可。