Im implementing a JWT authentication in my Spring app, but there are some...Strange issues here.

What im expecting to happen is just being able to access to a secured endpoint (/hello) after authenticate/generate my JWT token in my login endpoint (/auth/login, which naturally is a public endpoint).

I can request to /auth/login and receive my token with no problems, but when i try to use that token to access a secured endpoint i receive a 401 - Unauthorized - Access Denied exception...And thats all, i've compared my code to others implementations and honestly im not being able to find whats the deal here.

As a plus, heres a log (from the @EnableWebSecurity debug logger) from the /hello request: https://pastebin.com/YWYpucuS

Have a sample of my code:

//SecurityConfig.kt
@Configuration
@EnableWebSecurity(debug = true)
@EnableMethodSecurity(prePostEnabled = true)
class SecurityConfig {

    @Autowired
    private lateinit var _customUserDetailsService: CustomUserDetailsService

    @Autowired
    private lateinit var _jwtTokenFilter: JwtTokenFilter

    @Bean
    @Throws(Exception::class)
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        return http
            .cors { it.disable() }
            .csrf { it.disable() }
            .sessionManagement { it.sessionCreationPolicy(SessionCreationPolicy.STATELESS) }
            .headers { it.frameOptions { frameOption -> frameOption.sameOrigin() } }

            .exceptionHandling { exceptionHandling ->
                exceptionHandling.authenticationEntryPoint { _, response, ex ->
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.message)
                }

                exceptionHandling.accessDeniedHandler { _, response, ex ->
                    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, ex.message)
                }
            }

            .authorizeHttpRequests { authz ->
                authz
                    .requestMatchers("/auth/login").permitAll()
                    .requestMatchers("/error").permitAll()
                    .anyRequest().authenticated()
            }
            .addFilterBefore(_jwtTokenFilter, UsernamePasswordAuthenticationFilter::class.java)
            .build()
    }

    @Bean
    fun passwordEncoder(): PasswordEncoder {
        return object : BCryptPasswordEncoder() {
            override fun matches(rawPassword: CharSequence?, encodedPassword: String?): Boolean {
                return rawPassword == encodedPassword
            }
        }
    }

    @Bean
    fun authenticationManager(): AuthenticationManager {
        return CustomAuthenticationManager(_customUserDetailsService)
    }

}
//JwtTokenFilter.kt
class JwtTokenFilter: OncePerRequestFilter() {

    @Autowired
    private lateinit var _jwtTokenUtil: JwtTokenUtil

    @Autowired
    private lateinit var _userService: UserService

    @Throws(ServletException::class, IOException::class)
    override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {

        val jwtBearer = request.getHeader(HttpHeaders.AUTHORIZATION)

        if (jwtBearer == null || jwtBearer.isEmpty() || !jwtBearer.startsWith("Bearer ")) {
            chain.doFilter(request, response)
            return
        }

        val token = _jwtTokenUtil.resolveTokenFrom(jwtBearer)

        _jwtTokenUtil.validate(token)

        val user = _userService.findById(_jwtTokenUtil.getSubject(token).toLong())

        val auth = UsernamePasswordAuthenticationToken(
            UserIdentity(email = user.email!!, id = user.id!!), user.password
        )

        auth.details = WebAuthenticationDetailsSource().buildDetails(request)
        SecurityContextHolder.getContext().authentication = auth

        chain.doFilter(request, response)
    }
}

This same JWT implementation was working well in Spring Boot 2.x (of course, with some different method and functions that are now deprecated). Any questions or help is highly appreciated!

Comment From: sjohnr

@Sphirye, thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add a minimal sample that reproduces this issue if you feel this is a genuine bug.

Having said that, I want to point out that you have implemented a custom filter. Please consider using built-in support for JWT which can be used without OAuth2.

Comment From: CurrentIndex

@Sphirye, thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. We prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add a minimal sample that reproduces this issue if you feel this is a genuine bug.

Having said that, I want to point out that you have implemented a custom filter. Please consider using built-in support for JWT which can be used without OAuth2.

Can you provide simple examples of JWT or Oauth built-in support? Almost all the examples I see on the Internet need to implement their own custom filters like JwtFilter. I am very puzzled about this.

Comment From: sjohnr

@CurrentIndex as mentioned above, questions should be directed towards Stack Overflow. You can also browse the docs to find the information you're looking for. See the OAuth2 section for an example of using custom tokens.