I'm using Grails 3.1 and Spring security and I'm having trouble removing a filter from the Spring Security filterChain.
I need the filter to be executed only on the "/api/" endpoints. So, I'm trying to remove this filter from the "/auth/" and "/**" endpoints, but the filter is still being executed on all endpoints (including the ones set with 'filters: none').
Here's the chainMap defined in the application.groovy:
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: '/errors/**', filters: 'none'],
[pattern: '/auth/**', filters: 'JOINED_FILTERS,-tokenExpiryFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter,-rememberMeAuthenticationFilter'],
[pattern: '/api/**', filters: 'JOINED_FILTERS,-anonymousAuthenticationFilter,-exceptionTranslationFilter,-authenticationProcessingFilter,-securityContextPersistenceFilter'],
[pattern: '/**', filters: 'JOINED_FILTERS,-restTokenValidationFilter,-tokenExpiryFilter,-restExceptionTranslationFilter']
]
PS: Note the "-tokenExpiryFilter" on the endpoints that I'm trying to remove the filter
Beans in resources.groovy:
beans = {
tokenExpiryFilter(TokenExpiryFilter) {
tokenStorageService = ref('tokenStorageService')
userDetailsService = ref('userDetailsService')
}
}
Filter Implementation:
class TokenExpiryFilter extends GenericFilterBean {
TokenStorageService tokenStorageService
UserDetailsService userDetailsService
@Override
void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {
def httpRequest = ScriptBytecodeAdapter.asType(request, HttpServletRequest.class)
def httpResponse = ScriptBytecodeAdapter.asType(response, HttpServletResponse.class)
String token = extractTokenFromRequest(httpRequest)
if(token != null) {
UserDetails userDetails = tokenStorageService.loadUserByToken(token)
userDetails = userDetailsService.loadUserByUsername(userDetails.username)
if (!userDetails.accountNonExpired) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Expired account")
return
}
}
filterChain.doFilter(httpRequest, httpResponse)
}
private static String extractTokenFromRequest(HttpServletRequest request) {
String authorizationHeader = request.getHeader("Authorization")
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
return authorizationHeader.substring(7)
}
return authorizationHeader
}
}