Skip to content

OIDC JWT bearer token with empty file crashes the app #47630

@mocenas

Description

@mocenas

Describe the bug

Feature from PR #45131. When I set up token in my app like:

quarkus.oidc.client-id=quarkus-app
quarkus.oidc.credentials.jwt.source=bearer
quarkus.oidc.credentials.jwt.token-path=/tmp/bearer_token

If the file /tmp/bearer_token is missing, contains valid or invalid token it is OK - it either works or complains for missing/invalid token. But if the file /tmp/bearer_token is empty, the app crashes from start with below exception.

This is really annoying since if I create the file and start the app before the file is populated the app crashes straight away (token does not need to be used).

Failed to start application: java.lang.RuntimeException: Failed to start quarkus
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:119)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:80)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:51)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:144)
	at io.quarkus.runner.GeneratedMain.main(Unknown Source)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.doRun(QuarkusEntryPoint.java:68)
	at io.quarkus.bootstrap.runner.QuarkusEntryPoint.main(QuarkusEntryPoint.java:36)
Caused by: io.smallrye.mutiny.CompositeException: Multiple exceptions caught:
	[Exception 0] java.util.NoSuchElementException
	[Exception 1] io.quarkus.oidc.OIDCException
	at io.smallrye.mutiny.operators.uni.UniOnFailureFlatMap$UniOnFailureFlatMapProcessor.performInnerSubscription(UniOnFailureFlatMap.java:94)
	at io.smallrye.mutiny.operators.uni.UniOnFailureFlatMap$UniOnFailureFlatMapProcessor.dispatch(UniOnFailureFlatMap.java:83)
	at io.smallrye.mutiny.operators.uni.UniOnFailureFlatMap$UniOnFailureFlatMapProcessor.onFailure(UniOnFailureFlatMap.java:60)
	at io.smallrye.mutiny.operators.uni.UniOperatorProcessor.onFailure(UniOperatorProcessor.java:55)
	at io.smallrye.mutiny.operators.uni.UniOperatorProcessor.onFailure(UniOperatorProcessor.java:55)
	at io.smallrye.mutiny.operators.uni.UniOnItemOrFailureFlatMap$UniOnItemOrFailureFlatMapProcessor.performInnerSubscription(UniOnItemOrFailureFlatMap.java:91)
	at io.smallrye.mutiny.operators.uni.UniOnItemOrFailureFlatMap$UniOnItemOrFailureFlatMapProcessor.onItem(UniOnItemOrFailureFlatMap.java:54)
	at io.smallrye.mutiny.operators.uni.UniOnItemTransform$UniOnItemTransformProcessor.onItem(UniOnItemTransform.java:43)
	at io.smallrye.mutiny.operators.uni.UniOperatorProcessor.onItem(UniOperatorProcessor.java:47)
	at io.smallrye.mutiny.operators.uni.UniOperatorProcessor.onItem(UniOperatorProcessor.java:47)
	at io.smallrye.mutiny.operators.uni.builders.UniCreateFromPublisher$PublisherSubscriber.onNext(UniCreateFromPublisher.java:70)
	at io.smallrye.mutiny.subscription.MultiSubscriberAdapter.onItem(MultiSubscriberAdapter.java:27)
	at io.smallrye.mutiny.subscription.MultiSubscriber.onNext(MultiSubscriber.java:61)
	at io.smallrye.mutiny.subscription.SerializedSubscriber.onItem(SerializedSubscriber.java:74)
	at io.smallrye.mutiny.operators.multi.MultiRetryWhenOp$RetryWhenOperator.onItem(MultiRetryWhenOp.java:111)
	at io.smallrye.mutiny.subscription.MultiSubscriber.onNext(MultiSubscriber.java:61)
	at io.smallrye.mutiny.converters.uni.UniToMultiPublisher$UniToMultiSubscription.onItem(UniToMultiPublisher.java:94)
	at io.smallrye.mutiny.operators.uni.UniOnItemTransform$UniOnItemTransformProcessor.onItem(UniOnItemTransform.java:43)
	at io.smallrye.mutiny.vertx.AsyncResultUni.lambda$subscribe$1(AsyncResultUni.java:35)
	at io.smallrye.mutiny.vertx.DelegatingHandler.handle(DelegatingHandler.java:25)
	at io.vertx.ext.web.client.impl.HttpContext.handleDispatchResponse(HttpContext.java:403)
	at io.vertx.ext.web.client.impl.HttpContext.execute(HttpContext.java:385)
	at io.vertx.ext.web.client.impl.HttpContext.next(HttpContext.java:363)
	at io.vertx.ext.web.client.impl.HttpContext.fire(HttpContext.java:330)
	at io.vertx.ext.web.client.impl.HttpContext.dispatchResponse(HttpContext.java:292)
	at io.vertx.ext.web.client.impl.HttpContext.lambda$null$6(HttpContext.java:510)
	at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270)
	at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:252)
	at io.vertx.core.impl.ContextInternal.lambda$runOnContext$0(ContextInternal.java:50)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:840)
	Suppressed: io.quarkus.oidc.OIDCException
		at io.quarkus.oidc.runtime.TenantContextFactory$2.apply(TenantContextFactory.java:135)
		at io.quarkus.oidc.runtime.TenantContextFactory$2.apply(TenantContextFactory.java:116)
		at io.smallrye.context.impl.wrappers.SlowContextualFunction.apply(SlowContextualFunction.java:21)
		at io.smallrye.mutiny.groups.UniOnFailure.lambda$recoverWithItem$8(UniOnFailure.java:190)
		at io.smallrye.mutiny.operators.uni.UniOnFailureFlatMap$UniOnFailureFlatMapProcessor.performInnerSubscription(UniOnFailureFlatMap.java:92)
		... 36 more
	Caused by: java.util.NoSuchElementException
		at java.base/java.util.StringTokenizer.nextToken(StringTokenizer.java:347)
		at io.quarkus.oidc.common.runtime.OidcCommonUtils.getJwtContentPart(OidcCommonUtils.java:768)
		at io.quarkus.oidc.common.runtime.OidcCommonUtils.decodeJwtContent(OidcCommonUtils.java:758)
		at io.quarkus.oidc.common.runtime.ClientAssertionProvider.getExpiresAtFromExpClaim(ClientAssertionProvider.java:98)
		at io.quarkus.oidc.common.runtime.ClientAssertionProvider.loadFromFileSystem(ClientAssertionProvider.java:78)
		at io.quarkus.oidc.common.runtime.ClientAssertionProvider.<init>(ClientAssertionProvider.java:32)
		at io.quarkus.oidc.runtime.OidcProviderClientImpl.createClientAssertionProvider(OidcProviderClientImpl.java:91)
		at io.quarkus.oidc.runtime.OidcProviderClientImpl.<init>(OidcProviderClientImpl.java:81)
		at io.quarkus.oidc.runtime.TenantContextFactory$9.apply(TenantContextFactory.java:559)
		at io.quarkus.oidc.runtime.TenantContextFactory$9.apply(TenantContextFactory.java:526)
		at io.smallrye.context.impl.wrappers.SlowContextualBiFunction.apply(SlowContextualBiFunction.java:21)
		at io.smallrye.mutiny.operators.uni.UniOnItemOrFailureFlatMap$UniOnItemOrFailureFlatMapProcessor.performInnerSubscription(UniOnItemOrFailureFlatMap.java:86)
		... 31 more
Caused by: [CIRCULAR REFERENCE: java.util.NoSuchElementException]

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

No response

Quarkus version or git rev

No response

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions