0

I created a small project using Quarkus, Smallrye JWT, and Kotlin where a JWT token is generated. The token generation works fine when I'm running the app in JVM. However, when I build the application into native and I run the application, the token is not generated anymore.

Here are the steps that I took:

Setting Up

Private and Public Keys Generation

openssl genrsa -out PrivateKey.pem 2048
openssl rsa -in PrivateKey.pem -outform PEM -pubout -out PublicKey.pem

Then I moved the keys to the resources/META-INF/keys folder.

Updated the application.yml

smallrye:
  jwt:
    sign:
      key:
        location: "META-INF/keys/PrivateKey.pem"
    encrypt:
      key:
        location: "META-INF/keys/PublicKey.pem"
    verify:
      key:
        location: "META-INF/keys/PublicKey.pem"

The Code

TokenService

@ApplicationScoped
class TokenService {

    fun generateToken(): String {
        val now = Instant.now()
        return Jwt.claims()
            .subject(UUID.randomUUID().toString())
            .upn("johndoe@example.com")
            .groups(setOf("SOME ROLE"))
            .issuer("A Issuer")
            .issuedAt(now)
            .expiresIn(Duration.ofHours(1))
            .expiresAt(now.plus(1, ChronoUnit.HOURS))
            .claim(Claims.email, "johndoe@example.com")
            .claim(Claims.given_name, "John")
            .claim(Claims.family_name, "Doe")
            .claim(Claims.full_name, "John Doe")
            .claim("some_custom_claim", "a value")
            .sign()
    }
}

JwtController

@Path("/generate-token")
class JwtController(private val tokenService: TokenService) {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    fun generateToken(): Response {
        val token = tokenService.generateToken()
        return Response.ok(TokenResponse(token)).build()
    }
}

data class TokenResponse(
    @field:JsonProperty("token")
    val token: String
)

Building and Running

JVM

  • Java 17.0.8
  • Kotlin 1.9
openjdk version "17.0.8" 2023-07-18
OpenJDK Runtime Environment Temurin-17.0.8+7 (build 17.0.8+7)
OpenJDK 64-Bit Server VM Temurin-17.0.8+7 (build 17.0.8+7, mixed mode, sharing)
quarkus build
java -jar ./build/quarkus-app/quarkus-run.jar

Request

curl --request POST --url http://localhost:8080/generate-token

Response (200 OK)

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIzOGYwOTc1YS0zNjk1LTQxMDYtODUwNC1kZmZlYTk4ZGU5NWEiLCJ1cG4iOiJqb2huZG9lQGV4YW1wbGUuY29tIiwiZ3JvdXBzIjpbIlNPTUUgUk9MRSJdLCJpc3MiOiJBIElzc3VlciIsImlhdCI6MTY5MzIyMjA2NiwiZXhwIjoxNjkzMjI1NjY2LCJlbWFpbCI6ImpvaG5kb2VAZXhhbXBsZS5jb20iLCJnaXZlbl9uYW1lIjoiSm9obiIsImZhbWlseV9uYW1lIjoiRG9lIiwiZnVsbF9uYW1lIjoiSm9obiBEb2UiLCJzb21lX2N1c3RvbV9jbGFpbSI6ImEgdmFsdWUiLCJqdGkiOiJkOTE0ZmZmMy1mOGIzLTRlOTYtOGIzZC0zZTE5NjJlODg5YjgifQ.TBUy4RE82KcNop-Wfhbbml8vnZbO8zuY0DgnW9zIcfXYOBl60XubAMFspEzG90nV_au7IYiSvXIZW4AJV8XJhU56c9jC9LRB4c_z0TLfFnBAmxjNyBQ-3D8T2W3RwENnK9lwsMq789T4SuUzlNB8ouxDKO9x5UmDuKqym_SuH3z5PXDrfHqWbaMoiYK7v8ftKuK2HtuYlAokVO7dvFh1vRIUYoRGy1VmJSfk8QIRqXRGm5rWE9IkJFw5UDzcAF6L8WAWP4cYBeGzE49Xy3lG3J6MsY_FHN8ehUaa_ItKs-dANx-yW0oWJcmdS3kPjjN6kkuKGUTbcCsvxF5-IXdPHw"
}

Native Mode

sdk use java 23.r17-mandrel
quarkus build --native
./build/jwt-native-1.0.0-SNAPSHOT-runner

Request

curl --request POST --url http://localhost:8080/generate-token

Response (200 OK)

{}

As you can see, the token is generated fine when the application is running under JVM, but when running in native mode, everything looks fine, but the token is not generated. No error is shown in the logs.

The sample project is here: https://github.com/rgiaviti/bug-quarkus-jwt-generate-native-mode

Ocean
  • 19
  • 4
humungs
  • 1,144
  • 4
  • 25
  • 44
  • 1
    Looks like a problem with code elemination/reflection. Could you add `@RegisterForReflection` on `class TokenResponse`? – Turing85 Aug 28 '23 at 12:07
  • In [this guide](https://quarkus.io/guides/security-jwt#configuring-the-smallrye-jwt-extension-security-information) there additional information about how to include resources (e.g. publicKey.pem) to navtive image. Did you try it? – zforgo Aug 28 '23 at 12:16
  • @Turing85, that's it! I've added `@RegisterForReflection` and it worked! Thanks! – humungs Aug 28 '23 at 12:50
  • 1
    @zforgo, yes, I added this property: `quarkus.native.resources.includes=META-INF/keys/PublicKey.pem` in `application;yml`, but not worked. It worked with `@RegisterForReflection` without adding this property. – humungs Aug 28 '23 at 12:51

0 Answers0