我正在使用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
我在 Config.groovy 中的 controllerAnnotations.staticRules 没有指定任何 \api**
我的 filterChain.chainMap 看起来像这样
grails.plugin.springsecurity.filterChain.chainMap = [
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter', // Stateless chain
'/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter' // Traditional chain
]
实现它的控制器的注销方法上的安全注释是什么?我怎样才能使这项工作?
谢谢