Ошибка выхода из плагина spring-security-rest

Я использую spring-security-rest:1.5.0.RC2 с Grails 2.5.0. Я создал контроллер для информации профиля пользователя UserProfileController, который расширяет RestfulController. Вход в систему работает нормально, а также получение профиля пользователя. Однако, когда я пытаюсь \ api \ logout, я получаю

HTTP/1.1 403 Forbidden

При выходе из системы я указываю маркер Bearer, чтобы он правильно находил пользователя, но, похоже, он хочет использовать статические правила, чтобы определить, разрешен ли доступ к странице выхода из системы, и поскольку он не находит правило, если решает, что доступ запрещен. Это связано с пессимистической блокировкой страниц, представленной в последней версии grails. Смотрите журнал ниже.

2015-04-20 22:44:04,252 [http-bio-8080-exec-8] DEBUG matcher.AntPathRequestMatcher  - Checking match of request : '/api/logout'; against '/api/**'
2015-04-20 22:44:04,252 [http-bio-8080-exec-8] DEBUG web.FilterChainProxy  - /api/logout at position 1 of 7 in additional filter chain; firing Filter: 'MutableLogoutFilter'
2015-04-20 22:44:04,252 [http-bio-8080-exec-8] DEBUG web.FilterChainProxy  - /api/logout at position 2 of 7 in additional filter chain; firing Filter: 'RestAuthenticationFilter'
2015-04-20 22:44:04,252 [http-bio-8080-exec-8] DEBUG rest.RestAuthenticationFilter  - Actual URI is /api/logout; endpoint URL is /api/login
2015-04-20 22:44:04,252 [http-bio-8080-exec-8] DEBUG web.FilterChainProxy  - /api/logout at position 3 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2015-04-20 22:44:04,253 [http-bio-8080-exec-8] DEBUG web.FilterChainProxy  - /api/logout at position 4 of 7 in additional filter chain; firing Filter: 'GrailsAnonymousAuthenticationFilter'
2015-04-20 22:44:04,253 [http-bio-8080-exec-8] DEBUG filter.GrailsAnonymousAuthenticationFilter  - Populated SecurityContextHolder with anonymous token: 'grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationToken@dc4a600: Principal: org.springframework.security.core.userdetails.User@dc730200: Username: __grails.anonymous.user__; Password: [PROTECTED]; Enabled: false; AccountNonExpired: false; credentialsNonExpired: false; AccountNonLocked: false; Granted Authorities: ROLE_ANONYMOUS; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@0: RemoteIpAddress: fe80:0:0:0:414:abd0:23ec:bb74%10; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2015-04-20 22:44:04,253 [http-bio-8080-exec-8] DEBUG web.FilterChainProxy  - /api/logout at position 5 of 7 in additional filter chain; firing Filter: 'RestTokenValidationFilter'
2015-04-20 22:44:04,253 [http-bio-8080-exec-8] DEBUG bearer.BearerTokenReader  - Looking for bearer token in Authorization header, query string or Form-Encoded body parameter
2015-04-20 22:44:04,253 [http-bio-8080-exec-8] DEBUG bearer.BearerTokenReader  - Found bearer token in Authorization header
2015-04-20 22:44:04,253 [http-bio-8080-exec-8] DEBUG rest.RestTokenValidationFilter  - Token found: eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0Mjk1OTE0NDEsInN1YiI6InN3YXZlayIsInJvbGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwiaWF0IjoxNDI5NTg3ODQxfQ.am7f4VaQgdRWyMzBvfyT_jAmxeOZPhlURaNjdxVS6rM
2015-04-20 22:44:04,253 [http-bio-8080-exec-8] DEBUG rest.RestTokenValidationFilter  - Trying to authenticate the token
2015-04-20 22:44:04,254 [http-bio-8080-exec-8] DEBUG rest.RestAuthenticationProvider  - Trying to validate token eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0Mjk1OTE0NDEsInN1YiI6InN3YXZlayIsInJvbGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwiaWF0IjoxNDI5NTg3ODQxfQ.am7f4VaQgdRWyMzBvfyT_jAmxeOZPhlURaNjdxVS6rM
2015-04-20 22:44:04,254 [http-bio-8080-exec-8] DEBUG rest.JwtService  - Parsed an HMAC signed JWT
2015-04-20 22:44:04,256 [http-bio-8080-exec-8] DEBUG jwt.JwtTokenStorageService  - Successfully verified JWT
2015-04-20 22:44:04,256 [http-bio-8080-exec-8] DEBUG rest.JwtService  - Parsed an HMAC signed JWT
2015-04-20 22:44:04,257 [http-bio-8080-exec-8] DEBUG rest.RestAuthenticationProvider  - Now is Mon Apr 20 22:44:04 CDT 2015 and token expires at Mon Apr 20 23:44:01 CDT 2015
2015-04-20 22:44:04,257 [http-bio-8080-exec-8] DEBUG rest.RestAuthenticationProvider  - Expiration: 56
2015-04-20 22:44:04,258 [http-bio-8080-exec-8] DEBUG rest.RestAuthenticationProvider  - Authentication result: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0Mjk1OTE0NDEsInN1YiI6InN3YXZlayIsInJvbGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwiaWF0IjoxNDI5NTg3ODQxfQ.am7f4VaQgdRWyMzBvfyT_jAmxeOZPhlURaNjdxVS6rM, expiration:56, refreshToken:null, principal:org.springframework.security.core.userdetails.User@caf81bff: Username: swavek; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER, super:grails.plugin.springsecurity.rest.token.AccessToken@31b92fe9: Principal: org.springframework.security.core.userdetails.User@caf81bff: Username: swavek; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN, ROLE_USER)
2015-04-20 22:44:04,258 [http-bio-8080-exec-8] DEBUG rest.RestTokenValidationFilter  - Token authenticated. Storing the authentication result in the security context
2015-04-20 22:44:04,258 [http-bio-8080-exec-8] DEBUG rest.RestTokenValidationFilter  - Authentication result: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0Mjk1OTE0NDEsInN1YiI6InN3YXZlayIsInJvbGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwiaWF0IjoxNDI5NTg3ODQxfQ.am7f4VaQgdRWyMzBvfyT_jAmxeOZPhlURaNjdxVS6rM, expiration:56, refreshToken:null, principal:org.springframework.security.core.userdetails.User@caf81bff: Username: swavek; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER, super:grails.plugin.springsecurity.rest.token.AccessToken@31b92fe9: Principal: org.springframework.security.core.userdetails.User@caf81bff: Username: swavek; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN, ROLE_USER)
2015-04-20 22:44:04,259 [http-bio-8080-exec-8] DEBUG rest.RestTokenValidationFilter  - Continuing the filter chain
2015-04-20 22:44:04,259 [http-bio-8080-exec-8] DEBUG web.FilterChainProxy  - /api/logout at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2015-04-20 22:44:04,259 [http-bio-8080-exec-8] DEBUG web.FilterChainProxy  - /api/logout at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2015-04-20 22:44:04,260 [http-bio-8080-exec-8] DEBUG intercept.FilterSecurityInterceptor  - Secure object: FilterInvocation: URL: /api/logout; Attributes: [_DENY_]
2015-04-20 22:44:04,260 [http-bio-8080-exec-8] DEBUG intercept.FilterSecurityInterceptor  - Previously Authenticated: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0Mjk1OTE0NDEsInN1YiI6InN3YXZlayIsInJvbGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwiaWF0IjoxNDI5NTg3ODQxfQ.am7f4VaQgdRWyMzBvfyT_jAmxeOZPhlURaNjdxVS6rM, expiration:56, refreshToken:null, principal:org.springframework.security.core.userdetails.User@caf81bff: Username: swavek; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER, super:grails.plugin.springsecurity.rest.token.AccessToken@31b92fe9: Principal: org.springframework.security.core.userdetails.User@caf81bff: Username: swavek; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_ADMIN, ROLE_USER)
2015-04-20 22:44:04,260 [http-bio-8080-exec-8] DEBUG hierarchicalroles.RoleHierarchyImpl  - getReachableGrantedAuthorities() - From the roles [ROLE_ADMIN, ROLE_USER] one can reach [ROLE_ADMIN, ROLE_USER] in zero or more steps.
2015-04-20 22:44:04,261 [http-bio-8080-exec-8] DEBUG access.ExceptionTranslationFilter  - Access is denied (user is not anonymous); delegating to AccessDeniedHandler

Мой controllerAnnotations.staticRules в Config.groovy не указывает \api**

Мой filterChain.chainMap выглядит так

grails.plugin.springsecurity.filterChain.chainMap = [
    '/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter',  // Stateless chain
    '/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter'                                                                          // Traditional chain
]

Каковы аннотации безопасности на методе выхода из системы контроллера, реализующего его? Как я могу сделать эту работу?

Спасибо

1 ответ

Прежде всего, RestLogoutFilter не в цепочке. Но даже если бы это было так, при использовании JWT нет возможности выхода из системы. Цитирование документации:

Выход из системы невозможен при использовании токенов JWT (стратегия по умолчанию), так как на сервере не сохраняется состояние. Если вы все еще хотите выйти из системы, вы можете предоставить собственную реализацию, создав подкласс JwtTokenStorageService и переопределение методов storeToken а также removeToken, Затем зарегистрируйте вашу реализацию в resources.groovy как tokenStorageService,

Однако более рациональным подходом было бы просто удалить токен из клиента (например, из локального хранилища браузера) и позволить токенам истечь (они все равно истекут, в отличие от других хранилищ, таких как Memcached или Redis, где они обновляются при каждом доступе),

Другие вопросы по тегам