-
-
Notifications
You must be signed in to change notification settings - Fork 115
PUT/PATCH falling through to Spring Security? #169
Description
Hi -
First of all thanks for such a great plugin. It's been working great for the most part but I just ran into an issue that I can't find an answer to yet.
I have a REST based API in Grails and I just started trying to implement the PUT (i.e. update) capability of the API and when I try and access the application I'm getting a 403 Forbidden status response. From looking at the logs though it seems like the REST security plugin is authenticating properly but something else in the filterChain is blocking it possibly?
So I'm wondering if there is something I can put in Config.groovy or code that will allow this to work.
Thanks for any help and let me know if you need more information then I'm providing below.
Here's the relevant Config.groovy that I currently am using:
// Spring Security REST plugin configuration
grails.plugin.springsecurity.filterChain.chainMap = [
'/api/**': 'JOINED_FILTERS,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter', // Stateless chain
'/**': 'JOINED_FILTERS,-restTokenValidationFilter,-restExceptionTranslationFilter' // Traditional chain
]
grails.plugin.springsecurity.rest.token.validation.useBearerToken = false
grails.plugin.springsecurity.rest.token.validation.headerName = 'X-Auth-Token'
grails.plugin.springsecurity.rest.token.storage.useGorm = true
grails.plugin.springsecurity.rest.token.storage.gorm.tokenDomainClassName = 'com.qmedic.models.auth.AuthenticationToken'
grails.plugin.springsecurity.rest.token.storage.gorm.tokenValuePropertyName = 'tokenValue'
grails.plugin.springsecurity.rest.token.storage.gorm.usernamePropertyName = 'userName'
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.qmedic.models.auth.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.qmedic.models.auth.UserRole'
grails.plugin.springsecurity.authority.className = 'com.qmedic.models.auth.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
'/dbconsole/**': ['ROLE_ADMIN']
]
Here's the debug log from the console for a PUT request.
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG matcher.AntPathRequestMatcher - Checking match of request : '/api/studies/1/tasks'; against '/api/**'
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 1 of 8 in additional filter chain; firing Filter: 'RestLogoutFilter'
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 2 of 8 in additional filter chain; firing Filter: 'MutableLogoutFilter'
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 3 of 8 in additional filter chain; firing Filter: 'RestAuthenticationFilter'
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG rest.RestAuthenticationFilter - Actual URI is /api/studies/1/tasks; endpoint URL is /api/login
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 4 of 8 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 5 of 8 in additional filter chain; firing Filter: 'GrailsAnonymousAuthenticationFilter'
2015-02-11 12:54:34,870 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 6 of 8 in additional filter chain; firing Filter: 'RestTokenValidationFilter'
2015-02-11 12:54:34,871 [http-bio-8080-exec-2] DEBUG rest.RestTokenValidationFilter - Token found: kk063fl****************1fsi4qv2
2015-02-11 12:54:34,871 [http-bio-8080-exec-2] DEBUG rest.RestTokenValidationFilter - Trying to authenticate the token
2015-02-11 12:54:34,872 [http-bio-8080-exec-2] DEBUG rest.RestAuthenticationProvider - Trying to validate token kk063fl****************1fsi4qv2
2015-02-11 12:54:34,881 [http-bio-8080-exec-2] DEBUG rest.RestAuthenticationProvider - Authentication result: com.odobo.grails.plugin.springsecurity.rest.RestAuthenticationToken@e37cc6bd: Principal: com.company.auth.SpadesUserDetails@c7030e15: Username: testuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
2015-02-11 12:54:34,881 [http-bio-8080-exec-2] DEBUG rest.RestTokenValidationFilter - Token authenticated. Storing the authentication result in the security context
2015-02-11 12:54:34,881 [http-bio-8080-exec-2] DEBUG rest.RestTokenValidationFilter - Authentication result: com.odobo.grails.plugin.springsecurity.rest.RestAuthenticationToken@e37cc6bd: Principal: com.company.auth.SpadesUserDetails@c7030e15: Username: testuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
2015-02-11 12:54:34,881 [http-bio-8080-exec-2] DEBUG rest.RestTokenValidationFilter - Continuing the filter chain
2015-02-11 12:54:34,881 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 7 of 8 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2015-02-11 12:54:34,881 [http-bio-8080-exec-2] DEBUG web.FilterChainProxy - /api/studies/1/tasks at position 8 of 8 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2015-02-11 12:54:34,882 [http-bio-8080-exec-2] DEBUG intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /api/studies/1/tasks; Attributes: [_DENY_]
2015-02-11 12:54:34,882 [http-bio-8080-exec-2] DEBUG intercept.FilterSecurityInterceptor - Previously Authenticated: com.odobo.grails.plugin.springsecurity.rest.RestAuthenticationToken@e37cc6bd: Principal: com.company.auth.SpadesUserDetails@c7030e15: Username: testuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
2015-02-11 12:54:34,882 [http-bio-8080-exec-2] DEBUG hierarchicalroles.RoleHierarchyImpl - getReachableGrantedAuthorities() - From the roles [ROLE_USER] one can reach [ROLE_USER] in zero or more steps.
2015-02-11 12:54:34,892 [http-bio-8080-exec-2] DEBUG access.ExceptionTranslationFilter - Access is denied (user is not anonymous); delegating to AccessDeniedHandler
Message: Access is denied
Line | Method
->> 47 | decide in grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 107 | processFilterChain in com.odobo.grails.plugin.springsecurity.rest.RestTokenValidationFilter
| 73 | doFilter . . . . . in ''
| 53 | doFilter in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
| 122 | doFilter . . . . . in com.odobo.grails.plugin.springsecurity.rest.RestAuthenticationFilter
| 82 | doFilter in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 63 | doFilter . . . . . in com.odobo.grails.plugin.springsecurity.rest.RestLogoutFilter
| 82 | doFilter in com.brandseye.cors.CorsFilter
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . . . in java.lang.Thread