Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot security configuration ignoring permitted endpoints

I'm trying to get spring security with JWT to work with an app. I've read many tutorials and examples but nothing really fits my use case. We do not authorize via username/password, we use twilio to authenticate a mobile number, I then want to create a simple JWT token given a mobile number as the subject. I've been able to do that

here is a simple endpoint that exists in /api/v1/jwt

@GetMapping("/jwt")
    fun jwt(@RequestParam(value = "number", required = true) number: String): String? {

        val jwtToken = Jwts.builder().setSubject(number).claim("roles", "user").setIssuedAt(Date()).signWith(SignatureAlgorithm.HS256, Base64.getEncoder().encodeToString("secret".toByteArray())).compact()

        return jwtToken

    }

which returns a valid JWT token.

My security config isn't working anymore though, now all endpoints seem protected,

@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {

    @Bean
    override fun authenticationManagerBean(): AuthenticationManager {
        return super.authenticationManagerBean()
    }

    override fun configure(web: WebSecurity) {
        web.ignoring().antMatchers("/v2/api-docs",
                "/configuration/ui",
                "/swagger-resources/**",
                "/configuration/security",
                "/swagger-ui.html",
                "/webjars/**");
    }

    override fun configure(http: HttpSecurity) {

        http.csrf()
                .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/v1/auth/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(JwtFilter(), UsernamePasswordAuthenticationFilter::class.java)
    }
}

JWT Filter


    @Throws(IOException::class, ServletException::class)
    override fun doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
        val request = req as HttpServletRequest
        val response = res as HttpServletResponse
        val authHeader = request.getHeader("authorization")
        if ("OPTIONS" == request.method) {
            response.status = HttpServletResponse.SC_OK
            chain.doFilter(req, res)
        } else {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                throw ServletException("Missing or invalid Authorization header")
            }
            val token = authHeader.substring(7)
            try {
                val claims = Jwts.parser().setSigningKey(Base64.getEncoder().encodeToString("secret".toByteArray())).parseClaimsJws(token).body
                request.setAttribute("claims", claims)
            } catch (e: SignatureException) {
                throw ServletException("Invalid token")
            }
            chain.doFilter(req, res)
        }
    }
}

It seems the filter gets hit any time regardless of the permitall above it. Shouldn't the filter get ignored on any api/v1/auth/ path? I think im missing something.

Second question is there a way to apply this filter without having to addbefore or after and not extend https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.html

edit: antPathRequestMatcher isn't firing for configure, but I even added the path to websecurity configure, i get this logging

2019-12-30 14:44:44.792 DEBUG 81181 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy        : /api/v1/auth/request?number=5555555 has an empty filter list```
like image 457
Brian Avatar asked Dec 30 '19 18:12

Brian


People also ask

How do I exclude Spring Security auto configuration?

If you find that specific auto-configure classes are being applied that you don't want, you can use the exclude attribute of @EnableAutoConfiguration to disable them. If the class is not on the classpath, you can use the excludeName attribute of the annotation and specify the fully qualified name instead.

How do you restrict the endpoint of a spring boot?

Use Method-level Authorization To Restrict An Endpoint This tells Spring to check that the authenticated user has the Admin authority, and if not, deny the request. Run the app: ./gradlew bootRun . Navigate to http://localhost:8080/restricted . You'll get a 403 / Unauthorized whitepage error.

What should I use instead of WebSecurityConfigurerAdapter?

You need to declare SecurityFilterChain and WebSecurityCustomizer beans instead of overriding methods of WebSecurityConfigurerAdapter class.

What is anyRequest () authenticated ()?

anyRequest(). authenticated() is that any request must be authenticated otherwise my Spring app will return a 401 response.


1 Answers

You may use configure(web: WebSecurity), which will bypass the spring security filters and endpoints can be accessed publicly.

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

You might use configure(http: HttpSecurity) for session management and role-based authentication. You may see HttpSecurity vs WebSecurity.

For custom filters which have @Component(or any flavor of @Bean), WebSecurityConfigurerAdapter will tell Spring Security to ignore any filters added through it. The filter was then still being invoked because the @Component (or any flavor of @Bean) annotation told Spring to add the filter (again) outside of the security chain. So while the filter was being ignored in the security chain, it was not being ignored by the other (non-security?) chain. (See Here)

like image 92
Romil Patel Avatar answered Oct 25 '22 20:10

Romil Patel