私はspring-security-rest:1.5.0.RC2を Grails 2.5.0 で使用しています。RestfulController を拡張したユーザープロファイル情報 UserProfileController のコントローラーを作成しました。ログインは、ユーザー プロファイルの取得と同様に正常に機能します。ただし、 \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
]
実装しているコントローラのログアウト メソッドのセキュリティ アノテーションは何ですか? どうすればこれを機能させることができますか?
ありがとうございました