【问题标题】:Grails Spring Security Rest LogoutGrails Spring Security 休息注销
【发布时间】:2016-07-14 08:09:22
【问题描述】:

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

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

【问题讨论】:

    标签: logout grails-3.0 spring-security-rest


    【解决方案1】:

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

    Spring Security Rest plugin documentation 声明:

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

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

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

    【讨论】:

    • 你有任何教程来展示如何实现第一个建议吗? “如果您仍然想注销,您可以通过创建 JwtTokenStorageService 的子类并覆盖方法 storeToken 和 removeToken 来提供自己的实现。然后,在 resources.groovy 中将您的实现注册为 tokenStorageService。”
    • 不,我没有,但基本的想法很简单。您创建一个类似CustomJwtTokenStorageService 的类,并从JwtTokenStorageService 派生它。然后你实现一些存储和删除机制,并在 resources.groovy 中注册你的新服务,如docs.grails.org/latest/guide/spring.html 所述。要理解的重要一点是,您的 JWT 令牌实际上并未保存在您的服务器上,因此没有必要以这种方式实现注销机制,并且在客户端删除令牌就足够了。
    猜你喜欢
    • 2011-06-08
    • 2016-03-10
    • 2011-08-20
    • 1970-01-01
    • 2013-02-15
    • 2020-04-02
    • 2011-12-08
    • 2013-10-24
    • 2015-06-13
    相关资源
    最近更新 更多