grails-spring-security-core
grails-spring-security-core copied to clipboard
springSecurityService.principal returns Null when deployed as a WAR in tomcat 8.5
Task List
- [x] Steps to reproduce provided
- [x] DEBUG log (if present) provided
- [x] Example that reproduces the problem uploaded to Github. The link provided at the end.
- [x] Full description of the issue provided (see below)
Preamble
I'm designing an API gateway for a grails microservice federation. This issue seems related to a bunch of issues already filed. The closest issue is #482 (not exactly same). But I'm still unable to get around despite trying various suggestions. This question also gives a close problem but not the same.
Versions and Configurations
Grails: 3.2.2
Tomcat: 8.5
Application Name: umm
I'm using following plugin versions:
compile 'org.grails.plugins:spring-security-core:3.1.2'
compile "org.grails.plugins:spring-security-rest:2.0.0.M2"
Security configuration is as follows:
grails.plugin.springsecurity.sch.strategyName = org.springframework.security.core.context.SecurityContextHolder.MODE_INHERITABLETHREADLOCAL
grails.plugin.springsecurity.interceptUrlMap = [
[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: '/login', access: ['permitAll']],
[pattern: '/login/**', access: ['permitAll']],
[pattern: '/logout', access: ['permitAll']],
[pattern: '/logout/**', access: ['permitAll']],
[pattern: '/console/**', access: ["hasIpAddress(\'127.0.0.1\') || hasIpAddress(\'::1\')"]],
[pattern: '/static/console/**', access: ["hasIpAddress(\'127.0.0.1\') || hasIpAddress(\'::1\')"]],
[pattern: '/**', access: ['ROLE_NO_ROLES']]
]
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: '/console/**', filters: 'none'],
[pattern: '/static/console/**', filters: 'none'],
[pattern: '/**', filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,' +
'-exceptionTranslationFilter,-authenticationProcessingFilter,' +
'-securityContextPersistenceFilter,-rememberMeAuthenticationFilter']
]
I'm using spring security rest plugin for only token authentication. I'm doing the authorization part myself by returning ROLE_NO_ROLES
for all the users in getAuthorities().
I intercept all the requests and authorize the access based on my own authorization schema stored in DB. before()
method of my interceptor looks like following:
...
(microName, controller, action) = authorizationService.extractURI(request.forwardURI)
log.info("Requested URI is: " + request.forwardURI)
log.info("Name of the microservice is: " + microName)
log.info("Name of the controller is: " + controller)
log.info("Name of the action is: " + action)
log.info("Logged in user is " + springSecurityService.getCurrentUser())
micro = Microservice.findByName(microName)
if(microName != "umm"){
log.info("If authorized, request will be forwarded to: ${micro?.ipAddress}${req}")
}
if(!springSecurityService?.principal?.username){
log.info("Access denied. Token not provided in the header.")
resultSet.put("message", "Access denied. Token not provided in the header.")
response.status = 403
render resultSet as JSON
return false
}
...
Problem:
With these configurations and strategy, my code works as desired when I run it on my local system. When I deploy it on a server as a war file in tomcat, it works fine for all the requests to the gateway, i.e., for all requests of the pattern /umm/controller/action
. Spring security context is there and the user is evaluated perfectly.
When I try to call other microservices by redirection with requests of the form /umm/microservice/controller/action
, springSecurityService.getCurrentUser()
and springSecurityService?.principal?.username
start to return null. Although my token gets evaluated perfectly, yet I'm not getting any security context.
Following is the output for a failure case:
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Request '/pcsbackend/settings/getAllPromptFiles' matched by universal pattern '/**'
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles at position 1 of 7 in additional filter chain; firing Filter: 'SecurityRequestHolderFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles at position 2 of 7 in additional filter chain; firing Filter: 'MutableLogoutFilter'
DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/pcsbackend/settings/getAllPromptFiles'; against '/logoff'
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles at position 3 of 7 in additional filter chain; firing Filter: 'RestAuthenticationFilter'
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationFilter - Actual URI is /pcsbackend/settings/getAllPromptFiles; endpoint URL is /api/login
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles at position 4 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles at position 5 of 7 in additional filter chain; firing Filter: 'RestTokenValidationFilter'
DEBUG grails.plugin.springsecurity.rest.token.bearer.BearerTokenReader - Looking for bearer token in Authorization header, query string or Form-Encoded body parameter
DEBUG grails.plugin.springsecurity.rest.token.bearer.BearerTokenReader - Found bearer token in Authorization header
DEBUG grails.plugin.springsecurity.rest.token.bearer.BearerTokenReader - Token: eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RvbEFRbENvVkNRR3VoUzJ5cEhhTVZOQmdJU3NwR3FhQlNUUXhYNjRCK2M3OSs0TXlZSXl3Y0FBb2tXcTJxXC9BTjRHRkQxQ1ZnWldabFhlRzRNQ0Nlb3V0ZHpcL1wvXC9qMmYzVURGYVBnWWE4YUY4Vk9SeFZ6Nkp0VmN4Z2JEVEhQYjlUT0RPa0tiSTVaellJc21jSCs4RW5nQmxIaGs0WFd3eFhaWVZUQVpWeHZ0TFF4dHJhUGhnOUx4QStPbVpnbnVLcjN0UDNLSFN1TVRnWUxhKzEyQzRWV1laR0dvTW1uclNpNTJVcTR4V29XSlloYW9jTnVOM29SMGc5SnlKc3dnZEJnbGF3dU1BaGhsbWYybVNKV2pzZkRxM214bXVhZzIwZFlDR0VtWk1lVHVXWkttZGRiZHZiTXBLY0YzMklOeUpcL1hvVUhkekR1bzdIbjlCQ1VHcHVaSm10aVVURmZGTjdzU0p2emR6Y25uMHA5Y3FBVkFuNzFcLytwcGhQejBQdmZQMzJiVjYwRjFxWUdyQmV3R3FkbE54TUZzeGZOVHJsdjc4K1wvemk5T1ZnYkltV0hXUHJcL2ZjeCtlbWl1dTZDU2xHbG0xY0NPaUhhMzdONkpmUDVsOHY0V3VuNlRKNmxBK3FPa3hlaFJvaUNtdUdXdFJMOXZDMk5mR3NIaVJyMng0WjVOTjZtd0tPR1NoTWZ6M0c1aGZxQm9YWWZYeHhkSDdcLzRSeVFwVWRwaklrR3FmS0VEMUxHbWozajg3blJuOWVYV1loK2pcLzBIZG0rVnVGRkFNQUFBPT0iLCJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfTk9fUk9MRVMiXSwiZXhwIjoxNDk0OTI5MDE1LCJpYXQiOjE0OTQ5MjU0MTV9.R_UIO2sQ6Q6gPBPIcypQJRawHJroLPyxbKbUSNQfQLE
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Token found: eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RvbEFRbENvVkNRR3VoUzJ5cEhhTVZOQmdJU3NwR3FhQlNUUXhYNjRCK2M3OSs0TXlZSXl3Y0FBb2tXcTJxXC9BTjRHRkQxQ1ZnWldabFhlRzRNQ0Nlb3V0ZHpcL1wvXC9qMmYzVURGYVBnWWE4YUY4Vk9SeFZ6Nkp0VmN4Z2JEVEhQYjlUT0RPa0tiSTVaellJc21jSCs4RW5nQmxIaGs0WFd3eFhaWVZUQVpWeHZ0TFF4dHJhUGhnOUx4QStPbVpnbnVLcjN0UDNLSFN1TVRnWUxhKzEyQzRWV1laR0dvTW1uclNpNTJVcTR4V29XSlloYW9jTnVOM29SMGc5SnlKc3dnZEJnbGF3dU1BaGhsbWYybVNKV2pzZkRxM214bXVhZzIwZFlDR0VtWk1lVHVXWkttZGRiZHZiTXBLY0YzMklOeUpcL1hvVUhkekR1bzdIbjlCQ1VHcHVaSm10aVVURmZGTjdzU0p2emR6Y25uMHA5Y3FBVkFuNzFcLytwcGhQejBQdmZQMzJiVjYwRjFxWUdyQmV3R3FkbE54TUZzeGZOVHJsdjc4K1wvemk5T1ZnYkltV0hXUHJcL2ZjeCtlbWl1dTZDU2xHbG0xY0NPaUhhMzdONkpmUDVsOHY0V3VuNlRKNmxBK3FPa3hlaFJvaUNtdUdXdFJMOXZDMk5mR3NIaVJyMng0WjVOTjZtd0tPR1NoTWZ6M0c1aGZxQm9YWWZYeHhkSDdcLzRSeVFwVWRwaklrR3FmS0VEMUxHbWozajg3blJuOWVYV1loK2pcLzBIZG0rVnVGRkFNQUFBPT0iLCJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfTk9fUk9MRVMiXSwiZXhwIjoxNDk0OTI5MDE1LCJpYXQiOjE0OTQ5MjU0MTV9.R_UIO2sQ6Q6gPBPIcypQJRawHJroLPyxbKbUSNQfQLE
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Trying to authenticate the token
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Use JWT: true
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Trying to validate token eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RvbEFRbENvVkNRR3VoUzJ5cEhhTVZOQmdJU3NwR3FhQlNUUXhYNjRCK2M3OSs0TXlZSXl3Y0FBb2tXcTJxXC9BTjRHRkQxQ1ZnWldabFhlRzRNQ0Nlb3V0ZHpcL1wvXC9qMmYzVURGYVBnWWE4YUY4Vk9SeFZ6Nkp0VmN4Z2JEVEhQYjlUT0RPa0tiSTVaellJc21jSCs4RW5nQmxIaGs0WFd3eFhaWVZUQVpWeHZ0TFF4dHJhUGhnOUx4QStPbVpnbnVLcjN0UDNLSFN1TVRnWUxhKzEyQzRWV1laR0dvTW1uclNpNTJVcTR4V29XSlloYW9jTnVOM29SMGc5SnlKc3dnZEJnbGF3dU1BaGhsbWYybVNKV2pzZkRxM214bXVhZzIwZFlDR0VtWk1lVHVXWkttZGRiZHZiTXBLY0YzMklOeUpcL1hvVUhkekR1bzdIbjlCQ1VHcHVaSm10aVVURmZGTjdzU0p2emR6Y25uMHA5Y3FBVkFuNzFcLytwcGhQejBQdmZQMzJiVjYwRjFxWUdyQmV3R3FkbE54TUZzeGZOVHJsdjc4K1wvemk5T1ZnYkltV0hXUHJcL2ZjeCtlbWl1dTZDU2xHbG0xY0NPaUhhMzdONkpmUDVsOHY0V3VuNlRKNmxBK3FPa3hlaFJvaUNtdUdXdFJMOXZDMk5mR3NIaVJyMng0WjVOTjZtd0tPR1NoTWZ6M0c1aGZxQm9YWWZYeHhkSDdcLzRSeVFwVWRwaklrR3FmS0VEMUxHbWozajg3blJuOWVYV1loK2pcLzBIZG0rVnVGRkFNQUFBPT0iLCJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfTk9fUk9MRVMiXSwiZXhwIjoxNDk0OTI5MDE1LCJpYXQiOjE0OTQ5MjU0MTV9.R_UIO2sQ6Q6gPBPIcypQJRawHJroLPyxbKbUSNQfQLE
DEBUG grails.plugin.springsecurity.rest.token.storage.jwt.JwtTokenStorageService - Successfully verified JWT
DEBUG grails.plugin.springsecurity.rest.token.storage.jwt.JwtTokenStorageService - Trying to deserialize the principal object
DEBUG grails.plugin.springsecurity.rest.token.storage.jwt.JwtTokenStorageService - UserDetails deserialized: grails.plugin.springsecurity.userdetails.GrailsUser@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_NO_ROLES
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Now is Tue May 16 14:22:51 PKT 2017 and token expires at Tue May 16 15:03:35 PKT 2017
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Expiration: 2443
DEBUG grails.plugin.springsecurity.rest.RestAuthenticationProvider - Authentication result: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RvbEFRbENvVkNRR3VoUzJ5cEhhTVZOQmdJU3NwR3FhQlNUUXhYNjRCK2M3OSs0TXlZSXl3Y0FBb2tXcTJxXC9BTjRHRkQxQ1ZnWldabFhlRzRNQ0Nlb3V0ZHpcL1wvXC9qMmYzVURGYVBnWWE4YUY4Vk9SeFZ6Nkp0VmN4Z2JEVEhQYjlUT0RPa0tiSTVaellJc21jSCs4RW5nQmxIaGs0WFd3eFhaWVZUQVpWeHZ0TFF4dHJhUGhnOUx4QStPbVpnbnVLcjN0UDNLSFN1TVRnWUxhKzEyQzRWV1laR0dvTW1uclNpNTJVcTR4V29XSlloYW9jTnVOM29SMGc5SnlKc3dnZEJnbGF3dU1BaGhsbWYybVNKV2pzZkRxM214bXVhZzIwZFlDR0VtWk1lVHVXWkttZGRiZHZiTXBLY0YzMklOeUpcL1hvVUhkekR1bzdIbjlCQ1VHcHVaSm10aVVURmZGTjdzU0p2emR6Y25uMHA5Y3FBVkFuNzFcLytwcGhQejBQdmZQMzJiVjYwRjFxWUdyQmV3R3FkbE54TUZzeGZOVHJsdjc4K1wvemk5T1ZnYkltV0hXUHJcL2ZjeCtlbWl1dTZDU2xHbG0xY0NPaUhhMzdONkpmUDVsOHY0V3VuNlRKNmxBK3FPa3hlaFJvaUNtdUdXdFJMOXZDMk5mR3NIaVJyMng0WjVOTjZtd0tPR1NoTWZ6M0c1aGZxQm9YWWZYeHhkSDdcLzRSeVFwVWRwaklrR3FmS0VEMUxHbWozajg3blJuOWVYV1loK2pcLzBIZG0rVnVGRkFNQUFBPT0iLCJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfTk9fUk9MRVMiXSwiZXhwIjoxNDk0OTI5MDE1LCJpYXQiOjE0OTQ5MjU0MTV9.R_UIO2sQ6Q6gPBPIcypQJRawHJroLPyxbKbUSNQfQLE, expiration:2443, refreshToken:null, principal:grails.plugin.springsecurity.userdetails.GrailsUser@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_NO_ROLES, super:grails.plugin.springsecurity.rest.token.AccessToken@8d3530c3: Principal: grails.plugin.springsecurity.userdetails.GrailsUser@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_NO_ROLES; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_NO_ROLES)
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Token authenticated. Storing the authentication result in the security context
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Authentication result: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RvbEFRbENvVkNRR3VoUzJ5cEhhTVZOQmdJU3NwR3FhQlNUUXhYNjRCK2M3OSs0TXlZSXl3Y0FBb2tXcTJxXC9BTjRHRkQxQ1ZnWldabFhlRzRNQ0Nlb3V0ZHpcL1wvXC9qMmYzVURGYVBnWWE4YUY4Vk9SeFZ6Nkp0VmN4Z2JEVEhQYjlUT0RPa0tiSTVaellJc21jSCs4RW5nQmxIaGs0WFd3eFhaWVZUQVpWeHZ0TFF4dHJhUGhnOUx4QStPbVpnbnVLcjN0UDNLSFN1TVRnWUxhKzEyQzRWV1laR0dvTW1uclNpNTJVcTR4V29XSlloYW9jTnVOM29SMGc5SnlKc3dnZEJnbGF3dU1BaGhsbWYybVNKV2pzZkRxM214bXVhZzIwZFlDR0VtWk1lVHVXWkttZGRiZHZiTXBLY0YzMklOeUpcL1hvVUhkekR1bzdIbjlCQ1VHcHVaSm10aVVURmZGTjdzU0p2emR6Y25uMHA5Y3FBVkFuNzFcLytwcGhQejBQdmZQMzJiVjYwRjFxWUdyQmV3R3FkbE54TUZzeGZOVHJsdjc4K1wvemk5T1ZnYkltV0hXUHJcL2ZjeCtlbWl1dTZDU2xHbG0xY0NPaUhhMzdONkpmUDVsOHY0V3VuNlRKNmxBK3FPa3hlaFJvaUNtdUdXdFJMOXZDMk5mR3NIaVJyMng0WjVOTjZtd0tPR1NoTWZ6M0c1aGZxQm9YWWZYeHhkSDdcLzRSeVFwVWRwaklrR3FmS0VEMUxHbWozajg3blJuOWVYV1loK2pcLzBIZG0rVnVGRkFNQUFBPT0iLCJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfTk9fUk9MRVMiXSwiZXhwIjoxNDk0OTI5MDE1LCJpYXQiOjE0OTQ5MjU0MTV9.R_UIO2sQ6Q6gPBPIcypQJRawHJroLPyxbKbUSNQfQLE, expiration:2443, refreshToken:null, principal:grails.plugin.springsecurity.userdetails.GrailsUser@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_NO_ROLES, super:grails.plugin.springsecurity.rest.token.AccessToken@8d3530c3: Principal: grails.plugin.springsecurity.userdetails.GrailsUser@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_NO_ROLES; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_NO_ROLES)
DEBUG grails.plugin.springsecurity.rest.RestTokenValidationFilter - Continuing the filter chain
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
TRACE grails.plugin.springsecurity.web.access.intercept.InterceptUrlMapFilterInvocationDefinition - getAttributes(): url is /pcsbackend/settings/getallpromptfiles for FilterInvocation FilterInvocation: URL: /pcsbackend/settings/getAllPromptFiles
TRACE grails.plugin.springsecurity.web.access.intercept.InterceptUrlMapFilterInvocationDefinition - new candidate for '/pcsbackend/settings/getallpromptfiles': '/**':[ROLE_NO_ROLES]
TRACE grails.plugin.springsecurity.web.access.intercept.InterceptUrlMapFilterInvocationDefinition - config for '/pcsbackend/settings/getallpromptfiles' is '/**':[ROLE_NO_ROLES]
TRACE grails.plugin.springsecurity.web.access.intercept.InterceptUrlMapFilterInvocationDefinition - ConfigAttributes are [ROLE_NO_ROLES]
DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /pcsbackend/settings/getAllPromptFiles; Attributes: [ROLE_NO_ROLES]
DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Previously Authenticated: grails.plugin.springsecurity.rest.token.AccessToken(accessToken:eyJhbGciOiJIUzI1NiJ9.eyJwcmluY2lwYWwiOiJINHNJQUFBQUFBQUFBSlZTUDBcL2JRQlJcL0RvbEFRbENvVkNRR3VoUzJ5cEhhTVZOQmdJU3NwR3FhQlNUUXhYNjRCK2M3OSs0TXlZSXl3Y0FBb2tXcTJxXC9BTjRHRkQxQ1ZnWldabFhlRzRNQ0Nlb3V0ZHpcL1wvXC9qMmYzVURGYVBnWWE4YUY4Vk9SeFZ6Nkp0VmN4Z2JEVEhQYjlUT0RPa0tiSTVaellJc21jSCs4RW5nQmxIaGs0WFd3eFhaWVZUQVpWeHZ0TFF4dHJhUGhnOUx4QStPbVpnbnVLcjN0UDNLSFN1TVRnWUxhKzEyQzRWV1laR0dvTW1uclNpNTJVcTR4V29XSlloYW9jTnVOM29SMGc5SnlKc3dnZEJnbGF3dU1BaGhsbWYybVNKV2pzZkRxM214bXVhZzIwZFlDR0VtWk1lVHVXWkttZGRiZHZiTXBLY0YzMklOeUpcL1hvVUhkekR1bzdIbjlCQ1VHcHVaSm10aVVURmZGTjdzU0p2emR6Y25uMHA5Y3FBVkFuNzFcLytwcGhQejBQdmZQMzJiVjYwRjFxWUdyQmV3R3FkbE54TUZzeGZOVHJsdjc4K1wvemk5T1ZnYkltV0hXUHJcL2ZjeCtlbWl1dTZDU2xHbG0xY0NPaUhhMzdONkpmUDVsOHY0V3VuNlRKNmxBK3FPa3hlaFJvaUNtdUdXdFJMOXZDMk5mR3NIaVJyMng0WjVOTjZtd0tPR1NoTWZ6M0c1aGZxQm9YWWZYeHhkSDdcLzRSeVFwVWRwaklrR3FmS0VEMUxHbWozajg3blJuOWVYV1loK2pcLzBIZG0rVnVGRkFNQUFBPT0iLCJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfTk9fUk9MRVMiXSwiZXhwIjoxNDk0OTI5MDE1LCJpYXQiOjE0OTQ5MjU0MTV9.R_UIO2sQ6Q6gPBPIcypQJRawHJroLPyxbKbUSNQfQLE, expiration:2443, refreshToken:null, principal:grails.plugin.springsecurity.userdetails.GrailsUser@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_NO_ROLES, super:grails.plugin.springsecurity.rest.token.AccessToken@8d3530c3: Principal: grails.plugin.springsecurity.userdetails.GrailsUser@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_NO_ROLES; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_NO_ROLES)
DEBUG org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl - getReachableGrantedAuthorities() - From the roles [ROLE_NO_ROLES] one can reach [ROLE_NO_ROLES] in zero or more steps.
TRACE grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager - decide(): authenticatedVotersGranted=false otherVotersGranted=true
DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Authorization successful
DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - RunAsManager did not change Authentication object
DEBUG org.springframework.security.web.FilterChainProxy - /pcsbackend/settings/getAllPromptFiles reached end of additional filter chain; proceeding with original chain
DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
Requested URI is: /umm/pcsbackend/settings/getAllPromptFiles
Name of the microservice is: pcsbackend
Name of the controller is: settings
Name of the action is: getAllPromptFiles
If authorized, request will be forwarded to: http://192.168.1.79:8080/pcsbackend/settings/getAllPromptFiles
Logged in user is null
and the obvious response:
{
"status": {
"enumType": "org.springframework.http.HttpStatus",
"name": "FORBIDDEN"
},
"message": "Access denied. Token not provided in the header."
}
The whole project is available here if anyone wants to reproduce the issue on his machine. You can also open a pull request if the code is buggy. 📦
~## How to reproduce~
- ~Clone the repo from here.~
- ~Use
grails war
in the cloned directory.~ *~ Deploy the war file in any tomcat. (Tested in tomcat 8 and 7)~ - ~Get a token by sending a post request to /api/login with username = admin and password= admiN123!.~ *~ With this bearer token in the header, call /umm/user/list. Everything will work perfectly.~
- ~You can call any API given here and nothing breaks.~
- ~Call /umm/microservice/controller/action (any api that's not part of UMM), and there you have it. This conditional starts to return null.~
- ~Everything works perfectly with
grails run-app
even the URLs that are not part of UMM API.~
Look here: https://github.com/grails-plugins/grails-spring-security-core/issues/490#issuecomment-355517329 for reproducing the issue.
Update: May 19, 2017
I tried deploying my war in a Tomcat on my local machine. It still behaves the same. I also tried disabling tomcat cache and setting
grails.plugin.springsecurity.sch.strategyName = org.springframework.security.core.context.SecurityContextHolder.MODE_INHERITABLETHREADLOCAL
Nothing seems to work so far. SecurityContextHolder
is returning null
anyway. All the user retrieving functions of SpringSecurityService
viz. getCurrentUser()
, getPrincipal()
, getAuthentication()
and loadCurrentUser()
return null.
Update: May 23, 2017
To narrow down the problem, I executed the standalone war using
java -Dgrails.env=prod -jar build/libs/mywar-0.1.war
Now for any non-umm request, I get a 404, page not found
. ~I think the problem is with the production environment~. The app works completely fine in the development.
To rule out the problem with the production environment, I created the war using grails dev war
but to no avail. Nothing works so far for the war
.
Regards
I got a workaround fix. springSecurityService
is still returning null. I manually decoded the API token from the header and extracted username from it. This resolves my problem for now because I only needed the username. It is still incomprehensible that why the plugin is behaving this way. I'm not closing the issue yet.
def extractUsername(def token){
Base64 coder = new Base64()
def tok = token - "Bearer "
def principal = tok.tokenize(".")
def dec = coder.decode(principal[1])
def sub = new String(dec)
def user = sub.tokenize(",")
def username=user[1].tokenize(":")
username = username[1]-"\""
return username-"\""
}
I will check the issue @saqibahmed515 but I did not have the time yet.
I'm having same issue. Only when I create the war for tomcat 8.5
def user = springSecurityService.currentUser if(!user){ log.error "user not found." }
@barcelona23 do you have a sample project ?
@sdelamo Kindly have a look at following project: https://github.com/saqibahmed515/demoSpringSecurityIssue
Steps to reproduce:
- Configure DB setting in
application.yml
. I'm using mysql with DB namedemo
. - Build the application using
grails war
or./gradlew assemble
- Insert
*.war
file in the..../tomcat/webapps/
. - Access
localhost:8080/{appName}/user/index
. Credentials are admin:admin. - You'd see from GSP view that
springSecurityService
has perfect value in the interceptor butspringSecurityService.currentUser
is null. Getting current user here: https://github.com/saqibahmed515/demoSpringSecurityIssue/blob/master/grails-app/controllers/com/demo/issue/UserInterceptor.groovy#L16
Using
Grails
- Grails Version: 3.2.2
- Groovy Version: 2.4.7
Spring security
- Grails Spring Security Core: 3.1.2
- Grails Spring Security Rest: 2.0.0.M2
Tomcat
- Server version: Apache Tomcat/8.5.24
- Server built: Nov 27 2017 13:05:30 UTC
- Server number: 8.5.24.0
OS
- OS Name: Linux
- OS Version: 4.4.0-104-generic
- Architecture: amd64
JVM
- JVM Version: 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12
- JVM Vendor: Oracle Corporation
I'm getting following response when the application is deployed in above mentioned environment:
I have a similar problem. In my scenario i create a user that authenticates via external oauth 2 server and automatically login using springsecurity.reauthenticate. On jetbrains Idea that works but when deployed on tomcat, user has to logout first and login again to load user roles. When i list roles using ${currentUser?.authorities} it shows all the roles but on tomcat debug log, it says Authorities: ROLE_NO_ROLES. User first have to logout and login again.