Brian
Brian

Reputation: 4418

Spring Boot Security wont ignore certain paths that dont need to be secured

I've seen people post about this issue before. The problem is that I want everything in my /api/v1/auth/ controller to not go through the JWT filter chain.

This is what my my security config looks like

@Configuration
@EnableWebSecurity
class SecurityConfig() : WebSecurityConfigurerAdapter() {

    @Autowired
    lateinit var tokenService: TokenService

    override fun configure(web: WebSecurity) {
        web.ignoring().antMatchers(
                "/v2/api-docs",
                "/configuration/ui",
                "/swagger-resources/**",
                "/configuration/security",
                "/swagger-ui.html",
                "/webjars/**",
                "/api/v1/auth/**",
                "/api/v1/auth/request",
                "/api/v1/auth/verify",
                "/api/v1/auth/verify_hack",
                "/api/v1/auth/refresh_token",
                "/messages",
                "/index.html"
        )
    }

    override fun configure(http: HttpSecurity) {
        http.cors().and().csrf()
                .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/v1/auth/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(JwtFilter(tokenService), UsernamePasswordAuthenticationFilter::class.java)


    }
}

It sort of works before where if I hit an endpoint under /api/v1/auth and DONT add a Authorization header it seemed to bypass the jwt filter class, if I DO add an authorization header to any request it ALWAYS goes into the JWT filter class, I need it to completely ignore it which is what both the configure methods should be doing.

You might ask why not just not send the Auth header, well I specifically need it for the api/v1/auth/refresh_token endpoint

This is Spring Boot 2.3.0 so latest and greatest.

TLDR how the heck do I get security config to actually ignore paths

JWT filter

class JwtFilter(private val tokenService: TokenService) : GenericFilterBean() {

    override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {

        val token = TokenUtil.extractToken(request as HttpServletRequest)

        if (token != null && token.isNotEmpty()) {
            try {
                tokenService.getClaims(token)
            } catch (e: SignatureException) {
                throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid JWT Signature")
            } catch (e: MalformedJwtException) {
                throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Invalid JWT token")
            } catch (e: ExpiredJwtException) {
                throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Expired JWT token")
            } catch (e: UnsupportedJwtException) {
                throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unsupported JWT exception")
            } catch (e: IllegalArgumentException) {
                throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Jwt claims string is empty")
            }
        } else {
            throw ResponseStatusException(HttpStatus.UNAUTHORIZED, "Missing auth token")
        }
        chain.doFilter(request, response)
    }

}

Upvotes: 0

Views: 1901

Answers (2)

You can add this method to your JwtFilter

class JwtFilter(private val tokenService: TokenService) : GenericFilterBean() {

    override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
        if (request.getRequestURI().startsWith("/api/v1/auth/")) {
           filterChain.doFilter(request, response);
           return;
        }

        val token = TokenUtil.extractToken(request as HttpServletRequest)
        ....

Upvotes: 1

Kyito
Kyito

Reputation: 76

What you can do is add a validation on your filter to exclude the url that you don't want to filter.

add this code in your filter

String path = request.getRequestURI();
if ("/urltoexclude".equals(path)) {
    filterChain.doFilter(request, response);
    return;
}

here is more info about how to exclude url from your filter. https://www.baeldung.com/spring-exclude-filter

Upvotes: 0

Related Questions