Quarkus JWT Dasar- Security dengan Spesfifikasi MicroProfile JWT

1. Menambahkan Dependencies 

Jika Anda sudah memiliki proyek Quarkus yang terkonfigurasi, Anda dapat menambahkan ekstensi smallrye-jwt ke proyek Anda dengan menjalankan  salah satu perintah berikut di direktori dasar proyek (sesuai build tools anda):

  •  quarkus extension add smallrye-jwt,smallrye-jwt-build
  • ./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'
  • ./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build' 

2. Berikut hasilnya pada Maven Project:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-jwt</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-smallrye-jwt-build</artifactId>
</dependency>
 

Dan berikut hasil jika pada Gradle Project:

implementation("io.quarkus:quarkus-smallrye-jwt")
implementation("io.quarkus:quarkus-smallrye-jwt-build")

Penambahan Lines pada Khusus pada Gradle Project 

Pada build.gradle tambahkan lines berikut ini (Maven tidak perlu):

plugins {
id 'java'
id 'io.quarkus'
id 'application'
}

application {
mainClass = "com.yoesoff.plate.security.jwt.GenerateToken"
}

run {
systemProperty 'smallrye.jwt.sign.key.location', 'privateKey.pem'

3. Generate PEM Files

Buat pasangan public key dan private key dengan menggunakan OpenSSL command line tool dengan perintah OpenSSL untuk membuat kunci:

$ openssl genrsa -out rsaPrivateKey.pem 2048 

$ openssl rsa -pubout -in rsaPrivateKey.pem -out publicKey.pem

Langkah tambahan diperlukan untuk membuat dan mengonversi private key ke format PKCS#8, yang umum digunakan untuk penyimpanan dan pengiriman kunci secara aman.
Perintah OpenSSL untuk melakukan konversi: 

$ openssl pkcs8 -topk8 -nocrypt -inform pem -in rsaPrivateKey.pem -outform pem -out privateKey.pem

Rangkuman Semua Perintah Diatas

4. Penambahan Lines pada application.properties 

lokasi : src/main/resources/application.properties 

mp.jwt.verify.publickey.location=publicKey.pem
mp.jwt.verify.issuer=https://example.com/issuer
quarkus.native.resources.includes=publicKey.pem

 

5. File GenerateToken

Untuk file com.yoesoff.plate.security.jwt.GenerateToken ini akan diguanakn untuk membuat token via cli.

 

package com.yoesoff.plate.security.jwt;

import java.util.Arrays;
import java.util.HashSet;
import org.eclipse.microprofile.jwt.Claims;
import io.smallrye.jwt.build.Jwt;

public class GenerateToken {
public static void main(String[] args) {
String token = Jwt.issuer("https://example.com/issuer")
.upn("jdoe@quarkus.io")
.groups(new HashSet<>(Arrays.asList("User", "Admin")))
.claim(Claims.birthdate.name(), "2001-07-13")
.sign();
System.out.println(token);
System.exit(0);
}
}

Kode ini adalah program Java sederhana untuk membuat JWT (JSON Web Token) menggunakan SmallRye JWT.

  1. Package & Import

    • com.yoesoff.plate.security.jwt → lokasi paket kelas.

    • Mengimpor kelas dari io.smallrye.jwt.build.Jwt untuk membangun token JWT, serta Claims untuk klaim standar JWT.

  2. Class & Method

    • GenerateToken → nama kelas.

    • main → titik masuk program.

  3. Pembuatan Token

    issuer(...) → menetapkan penerbit token (URL asal token).

    upn(...) → menetapkan User Principal Name (identitas pengguna).

    groups(...) → menetapkan peran/role pengguna (User, Admin)

    claim(...) → menambahkan klaim kustom, di sini tanggal lahir.

    sign() → menandatangani token dengan kunci privat sesuai konfigurasi.

  4. Output

    System.out.println(token); → mencetak token JWT ke layar.

    System.exit(0); → menghentikan program setelah selesai.

     

6. Buat APIs Controller TokenSecuredResource 

package com.yoesoff.plate.security.jwt;

import jakarta.annotation.security.PermitAll;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.InternalServerErrorException;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.SecurityContext;
import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/secured")
public class TokenSecuredResource {
@Inject
JsonWebToken jwt;

@GET
@Path("permit-all")
@PermitAll
@Produces(MediaType.TEXT_PLAIN)
public String hello(@Context SecurityContext ctx) {
return getResponseString(ctx);
}

@GET
@Path("roles-allowed")
@RolesAllowed({ "User", "Admin" })
@Produces(MediaType.TEXT_PLAIN)
public String helloRolesAllowed(@Context SecurityContext ctx) {
return getResponseString(ctx) + ", birthdate: " + jwt.getClaim("birthdate").toString();
}


private String getResponseString(SecurityContext ctx) {
String name;
if (ctx.getUserPrincipal() == null) {
name = "anonymous";
} else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) {
throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
} else {
name = ctx.getUserPrincipal().getName();
}
return String.format("hello %s,"
+ " isHttps: %s,"
+ " authScheme: %s,"
+ " hasJWT: %s",
name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt());
}
private boolean hasJwt() {
return jwt.getClaimNames() != null;
}
}

7. Dapatkan Token via CLI (Server On!)

"Pastikan aplikasi sudah berjalan sebelum menghasilkan JSON Web Token (JWT) untuk endpoint TokenSecuredResource." 

Dapatkan Token Dengan Maven CLI

mvn exec:java -Dexec.mainClass=com.yoesoff.plate.security.jwt.GenerateToken -
Dexec.classpathScope=test -Dsmallrye.jwt.sign.key.location=privateKey.pem

Dapatkan Token Dengan Gradle CLI

./gradlew run -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dsmallrye.jwt.sign.key.location=privateKey.pem

 

8. HTTP Request Tanpa Token

curl -v http://127.0.0.1:8080/secured/roles-allowed; echo

 

Request Dengan Token 

Hit Dengan Curl 

 curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tL2lzc3VlciIsInVwbiI6Impkb2VAcXVhcmt1cy5pbyIsImdyb3VwcyI6WyJVc2VyIiwiQWRtaW4iXSwiYmlydGhkYXRlIjoiMjAwMS0wNy0xMyIsImlhdCI6MTc1NDYzOTY4MiwiZXhwIjoxNzU0NjM5OTgyLCJqdGkiOiI3MTUzNWJkYi03NGMyLTRkMmYtODE4Ny1lMmY4MDY4NDMxMmQifQ.RfsOQfybGpXINXIW7TQFWNwksrrFarpslDD2nYz5x-bAh-ufFFvE9rjHBNOdlan0E7pENUdKHgGL0PKiMhiUumDLwr1R8ZhJ5H6LIt9xy1sdy0v_7P6BFvY3nD_423UxisHw1Xmp5xlBlbEOgdJDM7bsiJFZqChOpip5ic_sS4v4dM3pV348Asv4uLDxPB974JjayjeHPBrHm7Keo_8LLkxyOz5j-fywi3rhDutGbAtU6ucV5dckPH_zqflf272vozC3QSzpI6HH3M1aN87q5UaQNqlif6tDy9wRYE6C7UxF7-cnBcu3JSONbsp1RJgv5o8kbZN9rj13werE2vQkVwAu" http://127.0.0.1:8080/secured/roles-allowed; echo

 

 

 Hit Dengan Postman 

  

Sumber: https://docs.redhat.com/en/documentation/red_hat_build_of_quarkus/3.20/pdf/microprofile_json_web_token_jwt_authentication/Red_Hat_build_of_Quarkus-3.20-Microprofile_JSON_Web_Token_JWT_authentication-en-US.pdf 

 

 

Comments

Popular posts from this blog

Numpang Kerja Remote dari Bandung Creative Hub

Debugging PHP Web dengan XDebug di Intellij IDEA (PHP STORM)

Numpang Kerja Remote dari Bandung Digital Valley