Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JWT token with HS256 and corresponding JWK file : UnresolvableKeyException #25632

Closed
Chanizo opened this issue May 17, 2022 · 10 comments · Fixed by #25653
Closed

JWT token with HS256 and corresponding JWK file : UnresolvableKeyException #25632

Chanizo opened this issue May 17, 2022 · 10 comments · Fixed by #25653
Labels
Milestone

Comments

@Chanizo
Copy link

Chanizo commented May 17, 2022

Describe the bug

My quarkus backend receives requests with JWT Token with some information.
I tried with quarkus-smallrye-jwt, and it worked for RS256 algorithm. I created a token with jwt.io and sent it with my request in my test, it has been correctly decoded.

To verify I simply used :
@Inject JsonWebToken jwt; ... @GET public Response get() { System.out.println(hasJwt()); System.out.println(jwt.getClaimNames());

I tried with pem file and jwk file then in smallrye.jwt.verify.key.location, and it was OK.
Then we moved to HS256 algorithm because of our needs, I created corresponding jwk file and token but this time it has not been working...

Expected behavior

I want to be able to simply use HS256 algorithm for encoding/decoding JWT Tokens with quarkus-smallrye-jwt

Actual behavior

I created JWKS file for HS256 algorithm with this format :
{ "keys": [ { "kty":"oct", "k":"uWlwBLGv4EpifZ52EhTuU9L-76AF9Vf4yumSD1P-2uE", "alg":"HS256" } ] }

I encoded a JWT token with HS256 and same secret, and sent it to quarkus back but I got this error :

2022-05-17 21:15:09,295 DEBUG [io.qua.sma.jwt.run.aut.MpJwtValidator] (executor-thread-0) Authentication failed: io.smallrye.jwt.auth.principal.ParseException: SRJWT07000: Failed to verify a token
at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parseClaims(DefaultJWTTokenParser.java:161)
at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parse(DefaultJWTTokenParser.java:56)
at io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipalFactory.parse(DefaultJWTCallerPrincipalFactory.java:31)
at io.smallrye.jwt.auth.principal.DefaultJWTParser.parse(DefaultJWTParser.java:64)
at io.smallrye.jwt.auth.principal.DefaultJWTParser_ClientProxy.parse(Unknown Source)
...
Caused by: org.jose4j.lang.UnresolvableKeyException: SRJWT07004: Failed to load a key from the key content while resolving
at io.smallrye.jwt.auth.principal.AbstractKeyLocationResolver.reportUnresolvableKeyException(AbstractKeyLocationResolver.java:187)
at io.smallrye.jwt.auth.principal.KeyLocationResolver.resolveKey(KeyLocationResolver.java:66)
at org.jose4j.jwt.consumer.JwtConsumer.processContext(JwtConsumer.java:213)
at org.jose4j.jwt.consumer.JwtConsumer.process(JwtConsumer.java:426)
at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parseClaims(DefaultJWTTokenParser.java:143)
... 74 more

How to Reproduce?

Add quarkus-smallrye-jwt dependency, create JWK file for HS256 algorithm, add it to smallrye.jwt.verify.key.location. Encode JWT token with same secret, with jwt.io for example, and add it in "Authorization" header of request for quarkus backend

Output of uname -a or ver

Darwin 21.4.0 Darwin Kernel Version 21.4.0: Fri Mar 18 00:45:05 PDT 2022; root:xnu-8020.101.4~15/RELEASE_X86_64 x86_64

Output of java -version

OpenJDK 64-Bit Server VM AdoptOpenJDK (build 14.0.2+12, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.8.1.Final

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

No response

Additional information

No response

@Chanizo Chanizo added the kind/bug Something isn't working label May 17, 2022
@quarkus-bot
Copy link

quarkus-bot bot commented May 17, 2022

/cc @sberyozkin

@sberyozkin
Copy link
Member

@Chanizo Thanks for opening this issue, I have this test in smallrye-jwt which uses this JWK.

Actually, I think I know why it may be failing. How do you create a signed token, does it have a kid (key identifier) set ? If it has a kid set then it will fail because your JWK key does not have a kid.
I think you also have to configure HS256 as smallrye.jwt.verify.algorithm - this is because by default it is RS256 and when a JWK key is loaded and this JWK has an alg set then it has to match the expected algorithm...

@Chanizo
Copy link
Author

Chanizo commented May 18, 2022

Thanks for your quick answer @sberyozkin !

I tried both (with and without kid), but it did not work...
I added smallrye.jwt.verify.algorithm=HS256 and used your JWK but same error

My JWK file :
{
"keys": [
{
"kty":"oct",
"k":"Fdh9u8rINxfivbrianbbVT1u232VQBZYKx1HGAGPt2I"
}
]
}

Result token with your JWK :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjEzMzIxMDcsImlhdCI6MTY2MTMzMjEwNywic3ViIjoidGVzdCIsImdpdmVuX25hbWUiOiJTdGV2ZSIsImZhbWlseV9uYW1lIjoiTWFuZGFuZGEiLCJ1c2VySWQiOiJNQU5EIn0.Zsl2WymJiyZYd5x_Y4ADnsew4wbDDrU2xXpXrUR-dRE

My parameters :
smallrye.jwt.verify.key.location=secret.jwks
smallrye.jwt.verify.algorithm=HS256

How I send the token :
given()
.when().header("Authorization", "Bearer " + JWT_TOKEN)
.get("/")
.then().assertThat().statusCode(200)

@sberyozkin
Copy link
Member

sberyozkin commented May 18, 2022

@Chanizo I've had a look and reproduced the problem locally.
The problem is that your key is not in JWK but in JWK Set format, i.e, an array of JWK keys, even though a single key is defined. At the moment smallrye-jwt does expect that a JWK set is only checked if the incoming token has a kid header - so that an individual JWK key can be identified in a JWK Set.
It can be relaxed a little bit - if the token kid is null and if JWK set has a single key only then it should work.
For now the simplest solution is to use a single JWK format:

{ "kty":"oct", "k":"uWlwBLGv4EpifZ52EhTuU9L-76AF9Vf4yumSD1P-2uE", "alg":"HS256" }

or add kid to both the token and the key in the JWK set

@sberyozkin
Copy link
Member

sberyozkin commented May 18, 2022

@Chanizo It is working now for me even with your case, I was wrong in my analysis, not sure why it was failing. smallrye-jwt does 2 tries, first at the initialization time, and then at the request time - when JWK set is used

@sberyozkin
Copy link
Member

@Chanizo FYI, #25653

@quarkus-bot quarkus-bot bot added this to the 2.10 - main milestone May 18, 2022
@Chanizo
Copy link
Author

Chanizo commented May 19, 2022

Thank you @sberyozkin, indeed the error for key location has disappeared, but I have a new one now...
It works, until I do a jwt.getClaimNames(), and then it raises a org.jose4j.jwt.consumer.InvalidJwtSignatureException
I took your jwk and put it in a jwk file :
{ "kty":"oct", "k":"uWlwBLGv4EpifZ52EhTuU9L-76AF9Vf4yumSD1P-2uE", "alg":"HS256" }

My application properties :
smallrye.jwt.verify.key.location=secret.jwk
smallrye.jwt.verify.algorithm=HS256

And the token signed with the new secret on jwt.io :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjEzMzIxMDcsImlhdCI6MTY2MTMzMjEwNywic3ViIjoidGVzdCIsImdpdmVuX25hbWUiOiJTdGV2ZSIsImZhbWlseV9uYW1lIjoiTWFuZGFuZGEiLCJ1c2VySWQiOiJNQU5EIn0.x9aQH2XhR9wIw6Wf1Xc3XE5lZwOiaGzmCTR21fJLlH0

My endpoint :
@Inject
JsonWebToken jwt;

@GET
public Response get() {
    System.out.println(jwt.getClaimNames());
    return;

Like last time, i did this call :
given()
.when()
.header("Authorization", "Bearer " + JWT_TOKEN)
.get("/")
.then().assertThat()
.statusCode(200)

This time it enters in my endpoint, but I got this error :
Caused by: org.jose4j.jwt.consumer.InvalidJwtSignatureException: JWT rejected due to invalid signature. Additional details: [[9] Invalid JWS Signature: JsonWebSignature{"alg":"HS256","typ":"JWT"}->eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjEzMzIxMDcsImlhdCI6MTY2MTMzMjEwNywic3ViIjoidGVzdCIsImdpdmVuX25hbWUiOiJTdGV2ZSIsImZhbWlseV9uYW1lIjoiTWFuZGFuZGEiLCJ1c2VySWQiOiJNQU5EIn0.x9aQH2XhR9wIw6Wf1Xc3XE5lZwOiaGzmCTR21fJLlH0]

@rodrigorodrigues
Copy link

Hi @Chanizo, did you manage to fix this?

My jwk is slightly different and couldn't find a way to make a valid call for the api always return 401 - unauthorized

jwk

{"keys":[{"kty":"RSA","e":"AQAB","n":"XXXX"}]}

application.properties

%consul.smallrye.jwt.verify.algorithm=HS256
smallrye.jwt.verify.key.location=${PUBLIC_KEY_PATH:/META-INF/resources/publicKey.pem}

Exception:

2022-10-08 23:36:57,232 DEBUG [io.sma.jwt.aut.principal] (vert.x-eventloop-thread-1) SRJWT08035: Checking if the key content is a Base64 encoded PEM key
2022-10-08 23:36:57,238 DEBUG [io.sma.jwt.aut.principal] (vert.x-eventloop-thread-1) SRJWT08037: The key content is not a valid encoded PEM key: java.lang.IllegalArgumentException: Illegal base64 character 7b
	at java.base/java.util.Base64$Decoder.decode0(Base64.java:848)
	at java.base/java.util.Base64$Decoder.decode(Base64.java:566)
	at java.base/java.util.Base64$Decoder.decode(Base64.java:589)
	at io.smallrye.jwt.util.KeyUtils.decodePublicKey(KeyUtils.java:276)
	at io.smallrye.jwt.auth.principal.KeyLocationResolver.tryAsPEMPublicKey(KeyLocationResolver.java:119)
	at io.smallrye.jwt.auth.principal.KeyLocationResolver.initializeKeyContent(KeyLocationResolver.java:99)
	at io.smallrye.jwt.auth.principal.KeyLocationResolver.<init>(KeyLocationResolver.java:45)
	at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.getVerificationKeyResolver(DefaultJWTTokenParser.java:242)
	at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parseClaims(DefaultJWTTokenParser.java:99)
	at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parse(DefaultJWTTokenParser.java:56)
	at io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipalFactory.parse(DefaultJWTCallerPrincipalFactory.java:31)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser.parse(DefaultJWTParser.java:64)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_Subclass.parse$$superforward1(Unknown Source)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_Subclass$$function$$6.apply(Unknown Source)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:51)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:33)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_Subclass.parse(Unknown Source)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_ClientProxy.parse(Unknown Source)
	at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator.createSecurityIdentity(MpJwtValidator.java:76)
	at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator$1.accept(MpJwtValidator.java:62)
	at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator$1.accept(MpJwtValidator.java:58)
	at io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:21)
	at io.smallrye.mutiny.operators.uni.builders.UniCreateWithEmitter.subscribe(UniCreateWithEmitter.java:22)
	at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
	at io.smallrye.mutiny.operators.uni.UniMemoizeOp.subscribe(UniMemoizeOp.java:84)
	at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
	at io.smallrye.mutiny.groups.UniSubscribe.withSubscriber(UniSubscribe.java:52)
	at io.quarkus.vertx.http.runtime.security.HttpSecurityRecorder$2.handle(HttpSecurityRecorder.java:113)
	at io.quarkus.vertx.http.runtime.security.HttpSecurityRecorder$2.handle(HttpSecurityRecorder.java:60)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:196)
	at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:185)
	at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
	at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	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:1534)

2022-10-08 23:36:57,262 DEBUG [io.sma.jwt.aut.principal] (vert.x-eventloop-thread-1) SRJWT08038: Checking if the key content is a Base64 encoded PEM certificate
2022-10-08 23:36:57,263 DEBUG [io.sma.jwt.aut.principal] (vert.x-eventloop-thread-1) SRJWT08040: The key content is not a valid encoded PEM certificate: java.lang.IllegalArgumentException: Illegal base64 character 7b
	at java.base/java.util.Base64$Decoder.decode0(Base64.java:848)
	at java.base/java.util.Base64$Decoder.decode(Base64.java:566)
	at java.base/java.util.Base64$Decoder.decode(Base64.java:589)
	at io.smallrye.jwt.util.KeyUtils.getCertificate(KeyUtils.java:370)
	at io.smallrye.jwt.auth.principal.AbstractKeyLocationResolver.loadPEMCertificate(AbstractKeyLocationResolver.java:321)
	at io.smallrye.jwt.auth.principal.KeyLocationResolver.tryAsPEMCertificate(KeyLocationResolver.java:128)
	at io.smallrye.jwt.auth.principal.KeyLocationResolver.initializeKeyContent(KeyLocationResolver.java:105)
	at io.smallrye.jwt.auth.principal.KeyLocationResolver.<init>(KeyLocationResolver.java:45)
	at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.getVerificationKeyResolver(DefaultJWTTokenParser.java:242)
	at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parseClaims(DefaultJWTTokenParser.java:99)
	at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parse(DefaultJWTTokenParser.java:56)
	at io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipalFactory.parse(DefaultJWTCallerPrincipalFactory.java:31)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser.parse(DefaultJWTParser.java:64)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_Subclass.parse$$superforward1(Unknown Source)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_Subclass$$function$$6.apply(Unknown Source)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.proceed(InvocationInterceptor.java:62)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor.monitor(InvocationInterceptor.java:51)
	at io.quarkus.arc.runtime.devconsole.InvocationInterceptor_Bean.intercept(Unknown Source)
	at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
	at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
	at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:33)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_Subclass.parse(Unknown Source)
	at io.smallrye.jwt.auth.principal.DefaultJWTParser_ClientProxy.parse(Unknown Source)
	at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator.createSecurityIdentity(MpJwtValidator.java:76)
	at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator$1.accept(MpJwtValidator.java:62)
	at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator$1.accept(MpJwtValidator.java:58)
	at io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:21)
	at io.smallrye.mutiny.operators.uni.builders.UniCreateWithEmitter.subscribe(UniCreateWithEmitter.java:22)
	at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
	at io.smallrye.mutiny.operators.uni.UniMemoizeOp.subscribe(UniMemoizeOp.java:84)
	at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)
	at io.smallrye.mutiny.groups.UniSubscribe.withSubscriber(UniSubscribe.java:52)
	at io.quarkus.vertx.http.runtime.security.HttpSecurityRecorder$2.handle(HttpSecurityRecorder.java:113)
	at io.quarkus.vertx.http.runtime.security.HttpSecurityRecorder$2.handle(HttpSecurityRecorder.java:60)
	at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
	at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
	at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
	at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:196)
	at io.quarkus.vertx.http.runtime.devmode.VertxHttpHotReplacementSetup$5.handle(VertxHttpHotReplacementSetup.java:185)
	at io.vertx.core.impl.future.FutureImpl$3.onSuccess(FutureImpl.java:141)
	at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:54)
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
	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:1534)

2022-10-08 23:36:57,264 DEBUG [io.sma.jwt.aut.principal] (vert.x-eventloop-thread-1) SRJWT08030: Checking if the key content is a JWK key or JWK key set
2022-10-08 23:36:57,266 DEBUG [io.sma.jwt.util] (vert.x-eventloop-thread-1) SRJWT01007: Trying to load the local JWK(S)...
2022-10-08 23:36:57,326 DEBUG [io.sma.jwt.aut.principal] (vert.x-eventloop-thread-1) SRJWT08026: Trying to create a key from the JWK(S)
2022-10-08 23:36:57,639 DEBUG [io.sma.jwt.aut.principal] (vert.x-eventloop-thread-1) SRJWT08004: Token is invalid

@elrob
Copy link

elrob commented Jan 16, 2024

Why is this configuration parameter required?
Why can't the verification use the algo from the JWT header?

I had a similar issue due to a JWT using PS256 algorithm. Adding the configuration parameter resolved the issue. But e.g. https://jwt.io/ automatically detects PS256 from the JWT header. And PS256 is present as the algorithm in the JWK JSON.

@weltonrodrigo
Copy link
Contributor

So that people coming from google can understand how to solve this.

JWK format expects a key in base64 format. In the example below, the OP used the raw value of uWlwBLGv4EpifZ52EhTuU9L-76AF9Vf4yumSD1P-2uE as the signing key to generate the example token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjEzMzIxMDcsImlhdCI6MTY2MTMzMjEwNywic3ViIjoidGVzdCIsImdpdmVuX25hbWUiOiJTdGV2ZSIsImZhbWlseV9uYW1lIjoiTWFuZGFuZGEiLCJ1c2VySWQiOiJNQU5EIn0.x9aQH2XhR9wIw6Wf1Xc3XE5lZwOiaGzmCTR21fJLlH0

instead of using the decode base64 value.

So, to be able to validate a token signed with the raw key uWlwBLGv4EpifZ52EhTuU9L-76AF9Vf4yumSD1P-2uE, the following JWKS file must be used:

{
  "keys": [
    {
      "kty": "oct",
      "k": "dVdsd0JMR3Y0RXBpZlo1MkVoVHVVOUwtNzZBRjlWZjR5dW1TRDFQLTJ1RQ==",
      "alg": "HS256"
    }
  ]
}

The application.properties settings to use (note that this is 2024-07-13 and the current quarkus version is 3.8.

  1. Put that Json Web Key Set into a file in your resources folder (src/main/resources/secretKey.jwk).
  2. Add those lines to your application.properties:
smallrye.jwt.verify.key.location=secretKey.jwk
smallrye.jwt.verify.algorithm=HS256

Make sure you have smallrye-jwt quarkus extension in your project.

Now token signed with the string uWlwBLGv4EpifZ52EhTuU9L-76AF9Vf4yumSD1P-2uE will be validated.

Thank you @sberyozkin, indeed the error for key location has disappeared, but I have a new one now... It works, until I do a jwt.getClaimNames(), and then it raises a org.jose4j.jwt.consumer.InvalidJwtSignatureException I took your jwk and put it in a jwk file : { "kty":"oct", "k":"uWlwBLGv4EpifZ52EhTuU9L-76AF9Vf4yumSD1P-2uE", "alg":"HS256" }

My application properties : smallrye.jwt.verify.key.location=secret.jwk smallrye.jwt.verify.algorithm=HS256

And the token signed with the new secret on jwt.io : eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjEzMzIxMDcsImlhdCI6MTY2MTMzMjEwNywic3ViIjoidGVzdCIsImdpdmVuX25hbWUiOiJTdGV2ZSIsImZhbWlseV9uYW1lIjoiTWFuZGFuZGEiLCJ1c2VySWQiOiJNQU5EIn0.x9aQH2XhR9wIw6Wf1Xc3XE5lZwOiaGzmCTR21fJLlH0

My endpoint : @Inject JsonWebToken jwt;

@GET
public Response get() {
    System.out.println(jwt.getClaimNames());
    return;

Like last time, i did this call : given() .when() .header("Authorization", "Bearer " + JWT_TOKEN) .get("/") .then().assertThat() .statusCode(200)

This time it enters in my endpoint, but I got this error : Caused by: org.jose4j.jwt.consumer.InvalidJwtSignatureException: JWT rejected due to invalid signature. Additional details: [[9] Invalid JWS Signature: JsonWebSignature{"alg":"HS256","typ":"JWT"}->eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NjEzMzIxMDcsImlhdCI6MTY2MTMzMjEwNywic3ViIjoidGVzdCIsImdpdmVuX25hbWUiOiJTdGV2ZSIsImZhbWlseV9uYW1lIjoiTWFuZGFuZGEiLCJ1c2VySWQiOiJNQU5EIn0.x9aQH2XhR9wIw6Wf1Xc3XE5lZwOiaGzmCTR21fJLlH0]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants