2

我正在使用 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)

有效,因此令牌肯定在令牌存储中。

我的 Spring Security 配置是

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']
]

我的配置中是否有错误或任何其他错误?

4

1 回答 1

2

提出问题后几分钟找到答案。

Spring Security Rest插件文档指出:

使用 JWT 令牌(默认策略)时无法注销,因为服务器中不会​​保留任何状态。如果您仍然想要注销,您可以通过创建 JwtTokenStorageService 的子类并覆盖方法 storeToken 和 removeToken 来提供自己的实现。然后,在 resources.groovy 中将您的实现注册为 tokenStorageService。

但是,更合理的方法是从客户端(例如,浏览器的本地存储)中删除令牌并让令牌过期(它们无论如何都会过期,不像其他存储,如 Memcached 或 Redis,它们在每次访问时都会刷新) .

因此,如果使用 JWT 进行授权,只需删除客户端上的令牌就足够了。

于 2016-03-26T18:30:36.187 回答