Hi, I'm currently using Spring Boot 3.0.0 and I wa...
# spring
p
Hi, I'm currently using Spring Boot 3.0.0 and I wanted to make use use of coroutines in my project. My back-end is acting as a OAuth 2 resource server with a custom JWT converter. Now when I make my controller functions suspendable, I'm getting a 401 back. I tried to propagate SecurityContext according to this article. But I'm still getting a 401 back. Did anyone by any chance had a similar problem?
r
I wrote that article a long time ago 😅 👴 The approach in the article describes a way to use coroutines in a 'traditional' Spring MVC project and still propagate the
SecurityContext
. But if you want suspendable controller functions, I would suggest using Spring WebFlux instead with reactive security, as described in the official Spring documentation
p
Didn’t expect to get a reply from you! hahah thanks I thought it still should work
r
not sure why it's not working, could you explain whether you're using: • Spring MVC or WebFlux • a reactive Spring Security config or a non-reactive and maybe provide the code of your controller, explaining what you would like it to do?
p
I'm using Spring MVC with non-reactive security. My goal is to add async call to an email service (which is quite slow) to the existing endpoints, so adding coroutines would speed it up a little
Copy code
@Bean
    fun filterChain(http: HttpSecurity): SecurityFilterChain {
        val whiteList = allowedUrls.split(",").toTypedArray()

        http
            .cors()
            .and()
            .authorizeHttpRequests()
            .requestMatchers(*whiteList).permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt()
            .jwtAuthenticationConverter(getJwtAuthenticationConverter())
        
        return http.build()
    }
This is basically the whole essence of my security config.
r
I suspect it might be related to the issue described in this StackOverflow thread: https://stackoverflow.com/a/75530224 (ignore the fact that the last comment actually suggests my blog again, lol) Just to verify this, I suspect your
@RestController
currently has something like this:
Copy code
@GetMapping("/some/url")
suspend fun myFunction(): MyReturnValue {
    // do some coroutine stuff, where somewhere you call withContext(SecurityCoroutineContext()) { ... }
    // or something like launch(SecurityCoroutineContext()) { ... } or similar
}
could you try to change it to the following structure, to see if my assumption is correct in that it might be something that's triggered by the way that Spring MVC calls suspending controller functions:
Copy code
@GetMapping("/some/url")
fun myFunction(): MyReturnValue = runBlocking(SecurityCoroutineContext()) {
    // do some coroutine stuff
}
p
That seems to solve my problem, thanks a lot!
r
great! although the better (or more proper) solution would be to go for Spring Webflux, this at least works when you're 'stuck' with Spring MVC but still want to use coroutines in certain places. Keep in mind of other mechanisms that in non-reactive environments rely on the thread context of the request that's being executed, like database transactions and logging MDC for example