Grails - Problem to Exclude a Filter from Specific Endpoints

27 views Asked by At

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
    }
}
0

There are 0 answers