Found blocking call.
I found Blocking call by BlockHound
in my spring webflux
app.
I know that jjwt uses SecureRandom
to make jwt id(jti)
in default.
Here is my stack traces.
reactor.blockhound.BlockingOperationError: Blocking call! java.io.FileInputStream#readBytes at
java.base/java.io.FileInputStream.readBytes(FileInputStream.java) ~[na:na] Suppressed:
reactor.core.publisher.FluxOnAssembly$OnAssemblyException: Error has been observed at the following
site(s): checkpoint ⇢ Handler
tokenserver.infrastructure.adapter.driving.web.auth.AuthController#issueAccessToken(IssueToken
Request) [DispatcherHandler] checkpoint ⇢ HTTP POST "/auth/token/access"
[ExceptionHandlingWebHandler] Original Stack Trace: at
java.base/java.io.FileInputStream.readBytes(FileInputStream.java) ~[na:na] at
java.base/java.io.FileInputStream.read(FileInputStream.java:276) ~[na:na] at
java.base/java.io.FilterInputStream.read(FilterInputStream.java:132) ~[na:na] at
java.base/sun.security.provider.NativePRNG$RandomIO.readFully(NativePRNG.java:425) ~[na:na] at
java.base/sun.security.provider.NativePRNG$RandomIO.ensureBufferValid(NativePRNG.java:528) ~[na:na]
at java.base/sun.security.provider.NativePRNG$RandomIO.implNextBytes(NativePRNG.java:547) ~[na:na]
at java.base/sun.security.provider.NativePRNG.engineNextBytes(NativePRNG.java:221) ~[na:na] at
java.base/java.security.SecureRandom.nextBytes(SecureRandom.java:758) ~[na:na] at
io.jsonwebtoken.impl.crypto.SignatureProvider.<clinit>(SignatureProvider.java:47) ~[jjwt-impl-0.11.5.jar!/:0.11.5] at
io.jsonwebtoken.impl.crypto.DefaultSignerFactory.createSigner(DefaultSignerFactory.java:36) ~[jjwt-impl-0.11.5.jar!/:0.11.5] at io.jsonwebtoken.impl.crypto.DefaultJwtSigner.<init>(DefaultJwtSigner.java:51) ~[jjwt-impl-0.11.5.jar!/:0.11.5] at
io.jsonwebtoken.impl.crypto.DefaultJwtSigner.<init>(DefaultJwtSigner.java:39) ~[jjwt-impl-0.11.5.jar!/:0.11.5] at
io.jsonwebtoken.impl.DefaultJwtBuilder.createSigner(DefaultJwtBuilder.java:360) ~[jjwt-impl-0.11.5.jar!/:0.11.5] at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.java:113)
~[jjwt-impl-0.11.5.jar!/:0.11.5] at
tokenserver.infrastructure.adapter.driven.jwt.JWTAdapter.issue(JWTAdapter.kt:34) ~[!/:0.0.1-SNAPSHOT] at
tokenserver.application.auth.usecase.AuthUseCase.issueToken$lambda$4(AuthUseCase.kt:38) ~[!/:0.0.1-SNAPSHOT] at reactor.core.publisher.MonoCallable.call(MonoCallable.java:72) ~[reactor-core-3.6.6.jar!/:3.6.6] at
reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:228) ~[reactor-core-3.6.6.jar!/:3.6.6] at
reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) ~[reactor-core-3.6.6.jar!/:3.6.6] at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28) ~[reactor-core-3.6.6.jar!/:3.6.6] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na] at
java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na] at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Edited blocking call to non-blocking
I edited code to use NativePRNGNonBlocking
SecureRandom
.
And then, blocking call was disappeared.
private val secureRandom = SecureRandom.getInstance("NativePRNGNonBlocking")
override fun issue(memberId: String, accessLevel: Int, type: TokenType): String {
val (secret, expiryDate) = helper.getSecretAndExpiry(type)
return Jwts.builder()
.signWith(Keys.hmacShaKeyFor(secret.toByteArray(StandardCharsets.UTF_8)), Jwts.SIG.HS256)
.subject(type.name)
.claim("memberId", memberId)
.claim("accessLevel", accessLevel)
.issuedAt(Date())
.expiration(Date(System.currentTimeMillis() + expiryDate))
.apply {
random(secureRandom)
}
.compact()
}
My Problem
Today, I reproduced the legacy code doesn’t use NativePRNGNonBlocking SecureRandom.
override fun issue(memberId: String, accessLevel: Int, type: TokenType): String {
val (secret, expiryDate) = helper.getSecretAndExpiry(type)
return Jwts.builder()
.signWith(Keys.hmacShaKeyFor(secret.toByteArray(StandardCharsets.UTF_8)), Jwts.SIG.HS256)
.subject(type.name)
.claim("memberId", memberId)
.claim("accessLevel", accessLevel)
.issuedAt(Date())
.expiration(Date(System.currentTimeMillis() + expiryDate))
.compact()
}
But, there isn’t blocking call even though it uses Default SecureRandom.
I wonder why there is no blocking call even though my code uses Default SecureRandom.
If SecureRandom doesn’t make blocking call, why blocking call found before???
Is it related about entropy pool???