이 콘텐츠는 선택한 언어로 제공되지 않습니다.
Chapter 1. Using JWT RBAC
This guide explains how to integrate SmallRye JWT into your Quarkus application to implement JSON Web Token (JWT) security in compliance with the MicroProfile JWT specification. You’ll learn how to verify JWTs, represent them as MicroProfile JWT org.eclipse.microprofile.jwt.JsonWebToken, and secure Quarkus HTTP endpoints using bearer token authorization and Role-Based Access Control.
The Quarkus OpenID Connect (quarkus-oidc) extension also supports bearer token authorization and uses smallrye-jwt to represent bearer tokens as JsonWebToken. For details, see the OIDC Bearer Token Authentication guide.
If your Quarkus application needs to authenticate users using the OIDC Authorization Code Flow, you must use the OpenID Connect extension. For more information, refer to the OIDC Code Flow Mechanism for Protecting Web Applications.
1.1. Prerequisites 링크 복사링크가 클립보드에 복사되었습니다!
To complete this guide, you need:
- Roughly 15 minutes
- An IDE
-
JDK 17+ installed with
JAVA_HOMEconfigured appropriately - Apache Maven 3.8.6 or later
- Optionally the Quarkus CLI if you want to use it
- Optionally Mandrel or GraalVM installed and configured appropriately if you want to build a native executable (or Docker if you use a native container build)
1.2. Quickstart 링크 복사링크가 클립보드에 복사되었습니다!
1.2.1. Solution 링크 복사링크가 클립보드에 복사되었습니다!
We recommend following the instructions in the upcoming sections to create the application step by step. If you prefer, you can skip ahead to the completed example.
To access the example, either clone the Git repository or download an archive:
-
Clone the repository:
git clone https://github.com/quarkusio/quarkus-quickstarts.git -b 3.27. - Download the archive.
The completed solution is located in the security-jwt-quickstart directory.
1.2.2. Creating the Maven project 링크 복사링크가 클립보드에 복사되었습니다!
First, create a new project with the following command:
Using the Quarkus CLI:
quarkus create app org.acme:security-jwt-quickstart \ --extension='rest-jackson,smallrye-jwt,smallrye-jwt-build' \ --no-code cd security-jwt-quickstartquarkus create app org.acme:security-jwt-quickstart \ --extension='rest-jackson,smallrye-jwt,smallrye-jwt-build' \ --no-code cd security-jwt-quickstartCopy to Clipboard Copied! Toggle word wrap Toggle overflow To create a Gradle project, add the
--gradleor--gradle-kotlin-dsloption.For more information about how to install and use the Quarkus CLI, see the Quarkus CLI guide.
Using Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow To create a Gradle project, add the
-DbuildTool=gradleor-DbuildTool=gradle-kotlin-dsloption.
For Windows users:
-
If using cmd, (don’t use backward slash
\and put everything on the same line) -
If using Powershell, wrap
-Dparameters in double quotes e.g."-DprojectArtifactId=security-jwt-quickstart"
This command generates the Maven project and imports the smallrye-jwt extension, which includes the MicroProfile JWT RBAC support.
If you already have your Quarkus project configured, you can add the smallrye-jwt extension to your project by running the following command in your project base directory:
Using the Quarkus CLI:
quarkus extension add smallrye-jwt,smallrye-jwt-build
quarkus extension add smallrye-jwt,smallrye-jwt-buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using Maven:
./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'
./mvnw quarkus:add-extension -Dextensions='smallrye-jwt,smallrye-jwt-build'Copy to Clipboard Copied! Toggle word wrap Toggle overflow Using Gradle:
./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build'
./gradlew addExtension --extensions='smallrye-jwt,smallrye-jwt-build'Copy to Clipboard Copied! Toggle word wrap Toggle overflow
This command adds the following dependencies to your build file:
Using Maven:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow Using Gradle:
implementation("io.quarkus:quarkus-smallrye-jwt") implementation("io.quarkus:quarkus-smallrye-jwt-build")implementation("io.quarkus:quarkus-smallrye-jwt") implementation("io.quarkus:quarkus-smallrye-jwt-build")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
1.2.3. Examine the Jakarta REST resource 링크 복사링크가 클립보드에 복사되었습니다!
Create a REST endpoint in src/main/java/org/acme/security/jwt/TokenSecuredResource.java with the following content:
REST endpoint V1
- 1
- The
JsonWebTokeninterface is injected, providing access to claims associated with the current authenticated token. This interface extendsjava.security.Principal. - 2
- The
@PermitAllis a standard Jakarta security annotation. It indicates that the given endpoint is accessible by all callers, whether authenticated or not. - 3
- The Jakarta REST
SecurityContextis injected to inspect the security state of the request. ThegetResponseString()function generates the response. - 4
- Checks if the call is insecure by checking if the request user/caller
Principalagainst null. - 5
- Ensures the names in the
PrincipalandJsonWebTokenmatch because theJsonWebTokenrepresents the currentPrincipal. - 6
- Retrieves the name of the
Principal. - 7
- Builds a response containing the caller’s name, the
isSecure()andgetAuthenticationScheme()states of the requestSecurityContext, and whether a non-nullJsonWebTokenwas injected.
1.2.4. Run the application in dev mode 링크 복사링크가 클립보드에 복사되었습니다!
Now, you are ready to run the application in dev mode by using one of the following commands:
Using the Quarkus CLI:
quarkus dev
quarkus devCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using Maven:
./mvnw quarkus:dev
./mvnw quarkus:devCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using Gradle:
./gradlew --console=plain quarkusDev
./gradlew --console=plain quarkusDevCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Then, you should see output similar to the following example:
quarkus:dev output
Now that the REST endpoint is running, you can access it by using a command line tool such as curl:
curl command for /secured/permit-all
curl http://127.0.0.1:8080/secured/permit-all; echo
$ curl http://127.0.0.1:8080/secured/permit-all; echo
This command returns the following response:
hello anonymous, isHttps: false, authScheme: null, hasJWT: false
hello anonymous, isHttps: false, authScheme: null, hasJWT: false
You have not provided any JWT in our request, so you would not expect the endpoint to see any security state, and the response is consistent with that:
-
usernameis anonymous. -
isHttpsisfalsebecausehttpsis not used. -
authSchemeisnull. -
hasJWTisfalse.
Use Ctrl-C to stop the Quarkus server.
So now let’s actually secure something. Take a look at the new endpoint method helloRolesAllowed in the following:
REST endpoint V2
- 1
- The
JsonWebTokenis injected to access claims from the JWT. - 2
- This endpoint is exposed at
/secured/roles-allowed. - 3
- The
@RolesAllowedannotation restricts access to users with either the "User" or "Admin" role. - 4
- The response is constructed similarly to the
hellomethod, with the addition of thebirthdateclaim retrieved directly from the injectedJsonWebToken.
After you make this addition to your TokenSecuredResource, rerun the ./mvnw quarkus:dev command, and then try curl -v http://127.0.0.1:8080/secured/roles-allowed; echo to attempt to access the new endpoint.
Your output should be as follows:
curl command for /secured/roles-allowed
curl -v http://127.0.0.1:8080/secured/roles-allowed; echo
$ curl -v http://127.0.0.1:8080/secured/roles-allowed; echo
This command returns the following response:
Excellent. You did not provide a JWT in the request, so access to the endpoint was correctly denied. Instead, you received an HTTP 401 Unauthorized error.
To access the endpoint, you must obtain and include a valid JWT in your request. This involves two steps:
- Configuring the SmallRye JWT extension with the necessary information to validate a JWT.
- Generating a JWT with the appropriate claims to match the configuration.
1.2.5. Configuring the SmallRye JWT extension security information 링크 복사링크가 클립보드에 복사되었습니다!
Create a security-jwt-quickstart/src/main/resources/application.properties with the following content:
Application properties for TokenSecuredResource
mp.jwt.verify.publickey.location=publicKey.pem mp.jwt.verify.issuer=https://example.com/issuer quarkus.native.resources.includes=publicKey.pem
mp.jwt.verify.publickey.location=publicKey.pem
mp.jwt.verify.issuer=https://example.com/issuer
quarkus.native.resources.includes=publicKey.pem
- 1
- Specifies the location of the public key file
publicKey.pemon the classpath. See Adding a public key for adding this key. - 2
- Defines the expected issuer as
https://example.com/issuer. - 3
- Ensures the
publicKey.pemfile is included as a resource in the native executable.
1.2.6. Adding a public key 링크 복사링크가 클립보드에 복사되었습니다!
The JWT specification defines various levels of security of JWTs that one can use. The MicroProfile JWT RBAC specification requires JWTs signed with the RSA-256 signature algorithm. This in turn requires an RSA public key pair. On the REST endpoint server side, you need to configure the location of the RSA public key to use to verify the JWT sent along with requests. The mp.jwt.verify.publickey.location=publicKey.pem setting configured previously expects that the public key is available on the classpath as publicKey.pem. To accomplish this, copy the following content to a security-jwt-quickstart/src/main/resources/publicKey.pem file.
RSA public key PEM content
1.2.7. Generating a JWT 링크 복사링크가 클립보드에 복사되었습니다!
Often, one obtains a JWT from an identity manager such as Keycloak. But for this quickstart, you generate our own by using the JWT generation API provided by smallrye-jwt. For more information, see Generate JWT tokens with SmallRye JWT.
Take the code from the following listing and place it into security-jwt-quickstart/src/test/java/org/acme/security/jwt/GenerateToken.java:
GenerateToken main driver class
- 1
- Sets the
iss(issuer) claim in the JWT. This value must match the server-sidemp.jwt.verify.issuerconfiguration for the token to be considered valid. - 2
- Specifies the
upn(User Principal Name) claim, which the MicroProfile JWT RBAC specification defines as the preferred claim for identifying thePrincipalin container security APIs. - 3
- Defines the
groupsclaim, which provides the group memberships and top-level roles assigned to the JWT bearer. - 4
- Adds a
birthdateclaim. Because this can be considered sensitive information, consider encrypting claims as described in Generate JWT tokens with SmallRye JWT.
Note that for this code to work, you need the content of the RSA private key corresponding to the public key you have in the TokenSecuredResource application. Take the following PEM content and place it into security-jwt-quickstart/src/test/resources/privateKey.pem:
RSA private key PEM content
Later, you configure the smallrye.jwt.sign.key.location property to specify the location of the private signing key.
It is also possible to generate a public and private key pair by using the OpenSSL command line tool.
openssl commands to generate keys
openssl genrsa -out rsaPrivateKey.pem 2048 openssl rsa -pubout -in rsaPrivateKey.pem -out publicKey.pem
openssl genrsa -out rsaPrivateKey.pem 2048
openssl rsa -pubout -in rsaPrivateKey.pem -out publicKey.pem
An additional step is required to generate and convert the private key to the PKCS#8 format, commonly used for secure key storage and transport.
openssl commands to perform the conversion
openssl pkcs8 -topk8 -nocrypt -inform pem -in rsaPrivateKey.pem -outform pem -out privateKey.pem
openssl pkcs8 -topk8 -nocrypt -inform pem -in rsaPrivateKey.pem -outform pem -out privateKey.pem
You can use the generated key pair instead of those used in this quickstart.
Ensure the application is running before generating the JSON Web Token (JWT) for the TokenSecuredResource endpoint.
Next, use the following command to generate the JWT:
Sample JWT generation output
mvn exec:java -Dexec.mainClass=org.acme.security.jwt.GenerateToken -Dexec.classpathScope=test -Dsmallrye.jwt.sign.key.location=privateKey.pem
$ mvn exec:java -Dexec.mainClass=org.acme.security.jwt.GenerateToken -Dexec.classpathScope=test -Dsmallrye.jwt.sign.key.location=privateKey.pem
The JWT string is a Base64 URL-encoded string consisting of three parts, separated by . characters:
- The header, which contains metadata about the token, such as the signing algorithm.
- The payload, also called "claims", which includes the token’s claims or data.
- The signature, which verifies the token’s integrity.
1.2.8. Finally, secured access to /secured/roles-allowed 링크 복사링크가 클립보드에 복사되었습니다!
Now, let’s use this to make a secured request to the /secured/roles-allowed endpoint. Make sure you have the Quarkus server still running in dev mode, and then run the following command, making sure to use your version of the generated JWT from the previous step:
curl command for /secured/roles-allowed with JWT
curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed; echo
$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed; echo
Make sure to use the generated token as the HTTP Authorization Bearer scheme value.
This command returns the following response:
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
Success! You now have the following:
-
A non-anonymous caller name:
jdoe@quarkus.io -
An authentication scheme:
Bearer -
A non-null
JsonWebToken -
The
birthdateclaim value
1.2.9. Using the JsonWebToken and claim injection 링크 복사링크가 클립보드에 복사되었습니다!
Now that you can generate a JWT to access our secured REST endpoints, let’s see what more you can do with the JsonWebToken interface and the JWT claims. The org.eclipse.microprofile.jwt.JsonWebToken interface extends the java.security.Principal interface, and is the object type returned by the jakarta.ws.rs.core.SecurityContext#getUserPrincipal() call you used previously. This means that code that does not use CDI but does have access to the REST container SecurityContext can get hold of the caller JsonWebToken interface by casting the SecurityContext#getUserPrincipal().
The JsonWebToken interface defines methods for accessing claims in the underlying JWT. It provides accessors for common claims that are required by the MicroProfile JWT RBAC specification and arbitrary claims that might exist in the JWT.
All the JWT claims can also be injected. Let’s expand our TokenSecuredResource with another endpoint /secured/roles-allowed-admin which uses the injected birthdate claim (as opposed to getting it from JsonWebToken):
- 1
- The
@RequestScopedscope is required to enable injection of thebirthdateclaim as aString. - 2
- The
JsonWebTokenis injected here, providing access to all claims and JWT-related information. - 3
- The
birthdateclaim is injected as aString. This highlights why the@RequestScopedscope is mandatory. - 4
- The injected
birthdateclaim is directly used to construct the response.
Now generate the token again and run:
curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed-admin; echo
$ curl -H "Authorization: Bearer eyJraWQ..." http://127.0.0.1:8080/secured/roles-allowed-admin; echo
Make sure to use the generated token as the HTTP Authorization Bearer scheme value.
This command returns the following response:
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
hello jdoe@quarkus.io, isHttps: false, authScheme: Bearer, hasJWT: true, birthdate: 2001-07-13
1.2.10. Run the application in JVM mode 링크 복사링크가 클립보드에 복사되었습니다!
You can run the application as a standard Java application.
Compile the application:
Using the Quarkus CLI:
quarkus build
quarkus buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using Maven:
./mvnw install
./mvnw installCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using Gradle:
./gradlew build
./gradlew buildCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Run the application:
java -jar target/quarkus-app/quarkus-run.jar
java -jar target/quarkus-app/quarkus-run.jarCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.2.11. Run the application in native mode 링크 복사링크가 클립보드에 복사되었습니다!
You can compile this same demo into native mode without any modifications. This implies that you no longer need to install a JVM on your production environment. The runtime technology is included in the produced binary and optimized to run with minimal resources required.
Compilation takes a bit longer, so this step is disabled by default.
Build your application again by enabling the
nativeprofile:Using the Quarkus CLI:
quarkus build --native
quarkus build --nativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using Maven:
./mvnw install -Dnative
./mvnw install -DnativeCopy to Clipboard Copied! Toggle word wrap Toggle overflow Using Gradle:
./gradlew build -Dquarkus.native.enabled=true
./gradlew build -Dquarkus.native.enabled=trueCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Run the following binary directly:
./target/security-jwt-quickstart-1.0.0-SNAPSHOT-runner
./target/security-jwt-quickstart-1.0.0-SNAPSHOT-runnerCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.2.12. Explore the solution 링크 복사링크가 클립보드에 복사되었습니다!
The security-jwt-quickstart directory repository contains all the versions covered in this quickstart guide, along with additional endpoints that demonstrate subresources using injected JsonWebToken tokens and their claims via CDI APIs.
We encourage you to explore the security-jwt-quickstart directory and review the quickstart solutions to learn more about the features of the SmallRye JWT extension.
1.3. Reference guide 링크 복사링크가 클립보드에 복사되었습니다!
1.3.1. Supported injection scopes 링크 복사링크가 클립보드에 복사되었습니다!
@ApplicationScoped, @Singleton and @RequestScoped outer bean injection scopes are all supported when an org.eclipse.microprofile.jwt.JsonWebToken is injected, with the @RequestScoped scoping for JsonWebToken enforced to ensure the current token is represented.
However, @RequestScoped must be used when the individual token claims are injected as simple types such as String, for example:
Note you can also use the injected JsonWebToken to access the individual claims, but setting @RequestScoped is unnecessary in this case.
Please see MP JWT CDI Injection Requirements for more details.
1.3.2. Supported public key formats 링크 복사링크가 클립보드에 복사되었습니다!
Public keys can be formatted in any of the following formats, specified in order of precedence:
- Public Key Cryptography Standards #8 (PKCS#8) PEM
- JSON Web Key (JWK)
- JSON Web Key Set (JWKS)
- JSON Web Key (JWK) Base64 URL encoded
- JSON Web Key Set (JWKS) Base64 URL encoded
1.3.3. Dealing with verification keys 링크 복사링크가 클립보드에 복사되었습니다!
If you need to verify the token signature by using the asymmetric RSA or Elliptic Curve (EC) key, use the mp.jwt.verify.publickey.location property to refer to the local or remote verification key.
Use mp.jwt.verify.publickey.algorithm to customize the verification algorithm (default is RS256); for example, set it to ES256 when working with the EC keys.
If you need to verify the token signature by using the symmetric secret key, then either a JSON Web Key (JWK) or JSON Web Key Set (JWK Set) format must be used to represent this secret key, for example:
This secret key JWK must also be referred to with smallrye.jwt.verify.key.location. smallrye.jwt.verify.algorithm should be set to HS256/HS384/HS512.
1.3.4. Parse and verify JsonWebToken with JWTParser 링크 복사링크가 클립보드에 복사되었습니다!
If the JWT token can not be injected, for example, if it is embedded in the service request payload or the service endpoint acquires it out of band, then one can use JWTParser:
You can also use it to customize how the token is verified or decrypted. For example, one can supply a local SecretKey:
Please also see the How to Add SmallRye JWT directly section about using JWTParser without the HTTP support provided by quarkus-smallrye-jwt.
1.3.5. Token decryption 링크 복사링크가 클립보드에 복사되었습니다!
If your application needs to accept tokens with encrypted claims or encrypted inner-signed claims, simply set the smallrye.jwt.decrypt.key.location property to point to the decryption key.
If this is the only key property set, the incoming token is expected to contain only encrypted claims. If either mp.jwt.verify.publickey or mp.jwt.verify.publickey.location verification properties are also set, then the incoming token is expected to contain the encrypted inner-signed token.
See Generate JWT tokens with SmallRye JWT and learn how to generate the encrypted or inner-signed and then encrypted tokens quickly.
1.3.6. Custom factories 링크 복사링크가 클립보드에 복사되었습니다!
The io.smallrye.jwt.auth.principal.DefaultJWTCallerPrincipalFactory is the default implementation used to parse and verify JWT tokens, converting them into JsonWebToken principals. This factory relies on the MP JWT and smallrye-jwt properties, as described in the Configuration section, to validate and customize JWT tokens.
If you need to implement a custom factory—such as to skip re-verifying tokens that have already been validated by a firewall—you can do so in one of the following ways:
-
Use the
ServiceLoadermechanism by creating aMETA-INF/services/io.smallrye.jwt.auth.principal.JWTCallerPrincipalFactoryresource. -
Provide an
AlternativeCDI bean implementation, like the example below:
1.3.7. Blocking calls 링크 복사링크가 클립보드에 복사되었습니다!
quarkus-smallrye-jwt extension uses SmallRye JWT library which is currently not reactive.
What it means from the perspective of quarkus-smallrye-jwt, which operates as part of the reactive Quarkus security architecture, is that an IO thread entering the SmallRye JWT verification or decryption code might block in one of the following cases:
-
The default key resolver refreshes the
JsonWebKeyset containing the keys, which involves a remote call to the OIDC endpoint. -
The custom key resolver, such as
AWS Application Load Balancer(ALB) key resolver, resolves the keys against the AWS ALB key endpoint by using the current token’s key identifier header value.
In such cases, if connections are slow—for instance, taking more than 3 seconds to respond to the key endpoint—the current event loop thread is likely to become blocked.
To prevent it from blocking, set quarkus.smallrye-jwt.blocking-authentication=true.
1.3.8. Token propagation 링크 복사링크가 클립보드에 복사되었습니다!
Please see the Token Propagation section about the Bearer access token propagation to the downstream services.
1.3.9. Testing 링크 복사링크가 클립보드에 복사되었습니다!
1.3.9.1. Automatic key generation 링크 복사링크가 클립보드에 복사되었습니다!
This extension generates an asymmetric RSA 2024 bit signing key pair in the dev and test modes if the verification key has not been configured. Once the key pair is generated, the public RSA key is used to configure the mp.jwt.verify.publickey property, and the RSA private key is available to tests to sign tokens using smallrye-jwt-build, for example:
See signing claims guide for mode details.
You can disable automatic key generation by setting at least one of the following properties:
-
mp.jwt.verify.publickey.location -
mp.jwt.verify.publickey -
mp.jwt.decrypt.key.location -
smallrye.jwt.encrypt.key.location -
smallrye.jwt.sign.key.location -
smallrye.jwt.sign.key
In dev mode, if you do not explicitly configure the issuer using the mp.jwt.verify.issuer property, the SmallRye JWT extension will set a default issuer of https://quarkus.io/issuer.
If you prefer to configure the issuer programmatically, set mp.jwt.verify.issuer to NONE to prevent the default value from being applied.
1.3.9.2. Wiremock 링크 복사링크가 클립보드에 복사되었습니다!
If you configure mp.jwt.verify.publickey.location to point to HTTPS or HTTP-based JsonWebKey (JWK) set, then you can use the same approach as described in the OpenID Connect Bearer Token Integration testing Wiremock section but only change the application.properties to use MP JWT configuration properties instead:
keycloak.url is set by OidcWiremockTestResource
# keycloak.url is set by OidcWiremockTestResource
mp.jwt.verify.publickey.location=${keycloak.url}/realms/quarkus/protocol/openid-connect/certs
mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus
1.3.9.3. Keycloak 링크 복사링크가 클립보드에 복사되었습니다!
If you work with Keycloak and configure mp.jwt.verify.publickey.location to point to HTTPS or HTTP-based JsonWebKey (JWK) set, you can use the same approach as described in the OpenID Connect Bearer Token Integration testing Keycloak section but only change the application.properties to use MP JWT configuration properties instead:
keycloak.url is set by DevServices for Keycloak
# keycloak.url is set by DevServices for Keycloak
mp.jwt.verify.publickey.location=${keycloak.url}/realms/quarkus/protocol/openid-connect/certs
mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus
Note that the tokens issued by Keycloak have an iss (issuer) claim set to the realm endpoint address.
If your Quarkus application runs in a Docker container, it might share a network interface with a Keycloak container started by DevServices for Keycloak. In this scenario, the Quarkus application and Keycloak communicate through an internal shared Docker network.
In such cases, use the following configuration instead:
1.3.9.4. Local public key 링크 복사링크가 클립보드에 복사되었습니다!
You can use the same approach as described in the OpenID Connect Bearer Token Integration testing Local public key section but only change the application.properties to use MP JWT configuration properties instead:
1.3.9.5. TestSecurity annotation 링크 복사링크가 클립보드에 복사되었습니다!
Add the following dependency:
Using Maven:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-security-jwt</artifactId> <scope>test</scope> </dependency><dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-test-security-jwt</artifactId> <scope>test</scope> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Using Gradle:
testImplementation("io.quarkus:quarkus-test-security-jwt")testImplementation("io.quarkus:quarkus-test-security-jwt")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Then, write test code such as this:
where the ProtectedResource class might look like this:
Note that the @TestSecurity annotation must always be used, and its user property is returned as JsonWebToken.getName() and roles property - as JsonWebToken.getGroups(). @JwtSecurity annotation is optional and can be used to set the additional token claims.
@TestSecurity and @JwtSecurity can be combined in a meta-annotation, as follows:
This is particularly useful if the same set of security settings needs to be used in multiple test methods.
1.3.10. How to check the errors in the logs 링크 복사링크가 클립보드에 복사되었습니다!
Please enable io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator TRACE level logging to see more details about the token verification or decryption errors:
quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".level=TRACE quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".min-level=TRACE
quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".level=TRACE
quarkus.log.category."io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator".min-level=TRACE
1.3.11. Proactive authentication 링크 복사링크가 클립보드에 복사되었습니다!
If you’d like to skip the token verification when the public endpoint methods are invoked, disable the proactive authentication.
Note that you can’t access the injected JsonWebToken through public methods if token verification has not been done.
1.3.12. How to add SmallRye JWT directly 링크 복사링크가 클립보드에 복사되었습니다!
To parse and verify JsonWebToken with JWTParser, use smallrye-jwt instead of quarkus-smallrye-jwt directly for the following situations:
-
You work with Quarkus extensions that do not support
HTTP, such asQuarkus GRPC. -
You provide an extension-specific
HTTP, the support of which conflicts with the support of those offered byquarkus-smallrye-jwtandVert.x HTTP, such asQuarkus AWS Lambda.
Start with adding the smallrye-jwt dependency:
Using Maven:
<dependency> <groupId>io.smallrye</groupId> <artifactId>smallrye-jwt</artifactId> </dependency><dependency> <groupId>io.smallrye</groupId> <artifactId>smallrye-jwt</artifactId> </dependency>Copy to Clipboard Copied! Toggle word wrap Toggle overflow Using Gradle:
implementation("io.smallrye:smallrye-jwt")implementation("io.smallrye:smallrye-jwt")Copy to Clipboard Copied! Toggle word wrap Toggle overflow
Then, update application.properties to get all the CDI producers provided by smallrye-jwt included as follows:
quarkus.index-dependency.smallrye-jwt.group-id=io.smallrye quarkus.index-dependency.smallrye-jwt.artifact-id=smallrye-jwt
quarkus.index-dependency.smallrye-jwt.group-id=io.smallrye
quarkus.index-dependency.smallrye-jwt.artifact-id=smallrye-jwt
1.4. Configuration reference 링크 복사링크가 클립보드에 복사되었습니다!
1.4.1. Quarkus configuration 링크 복사링크가 클립보드에 복사되었습니다!
🔒 Fixed at build time: Configuration property fixed at build time - All other configuration properties are overridable at runtime
| Configuration property | Type | Default |
|
🔒 Fixed at build time The MP-JWT configuration object
Environment variable: | boolean |
|
|
🔒 Fixed at build time
The name of the
Environment variable: | string |
|
|
Enable this property if fetching the remote keys can be a time-consuming operation. Do not enable it if you use the local keys.
Environment variable: | boolean |
|
|
Always create HTTP 401 challenge, even for requests containing no authentication credentials. JWT authentication mechanism will return HTTP 401 when an authentication challenge is required. However if it is used alongside one of the interactive authentication mechanisms then returning HTTP 401 to the users accessing the application from a browser may not be desired. If you prefer you can request that JWT authentication mechanism does not create a challenge in such cases by setting this property to 'true'.
Environment variable: | boolean |
|
1.4.2. MicroProfile JWT configuration 링크 복사링크가 클립보드에 복사되었습니다!
| Property Name | Default | Description |
|---|---|---|
|
|
|
The |
|
|
|
Config property allows for a specified external or internal location of the public key. The value can be a relative path or a URL. If the value points to an HTTPS-based JWK set, then, for it to work in native mode, the |
|
|
|
List of signature algorithms. Set it to |
|
|
| Config property allows for a specified external or internal location of the Private Decryption Key. |
|
|
|
List of decryption algorithms. Set it to |
|
|
|
Config property specifies the value of the |
|
|
|
Comma-separated list of audiences a token |
|
|
| Clock skew in seconds used during the token expiration and age verification. An expired token is accepted if the current time is within the number of seconds specified by this property after the token expiration time. The default value is 60 seconds. |
|
|
|
Number of seconds that must not elapse since the token |
|
|
|
Set this property if another header, such as |
|
|
|
Name of the cookie containing a token. This property is effective only if |
1.4.3. Additional SmallRye JWT configuration 링크 복사링크가 클립보드에 복사되었습니다!
SmallRye JWT provides more properties that can be used to customize the token processing:
| Property Name | Default | Description |
|---|---|---|
|
|
| Secret key supplied as a string. |
|
|
| Location of the verification key, which can point to both public and secret keys. Secret keys can only be in the JWK format. Note that 'mp.jwt.verify.publickey.location' is ignored if this property is set. |
|
|
Signature algorithm. This property should only be used to set a symmetric algorithm such as | |
|
|
|
Set this property to a specific key format such as |
|
|
|
By default, PEM, JWK, or JWK key sets can be read from the local file system or fetched from URIs as required by MicroProfile JWT specification. Set this property to |
|
|
|
Relax the validation of the verification keys; setting this property to |
|
|
| If this property is enabled, a signed token must contain either 'x5t' or 'x5t#S256' X509Certificate thumbprint headers. Verification keys can only be in JWK or PEM Certificate key formats. JWK keys must have an 'x5c' (Base64-encoded X509Certificate) property set. |
|
|
|
Set this property if another header, such as |
|
|
|
Key cache size. Use this property and |
|
|
|
Key cache entry time-to-live in minutes. Use this property and |
|
|
|
Name of the cookie containing a token. This property is effective only if |
|
|
|
Set this property to |
|
|
|
Comma-separated list containing alternative single or multiple schemes, such as |
|
|
|
Key identifier. The verification JWK key and every JWT token must have a matching |
|
|
| The maximum number of seconds a JWT can be issued for use. Effectively, the difference between the expiration date of the JWT and the issued at date must not exceed this value. Setting this property to a non-positive value relaxes the requirement for the token to have a valid 'iat' (issued at) claim. |
|
|
|
If an application relies on |
|
|
|
Path to the claim containing the subject name. It starts from the top-level JSON object and can contain multiple segments where each segment only represents a JSON object name, for example, |
|
|
|
This property can set a default sub claim value when the current token has no standard or custom |
|
|
|
Path to the claim containing the groups. It starts from the top-level JSON object and can contain multiple segments where each segment represents a JSON object name only, for example: |
|
|
|
Separator for splitting a string which might contain multiple group values. It is only used if the |
|
|
| This property can set a default groups claim value when the current token has no standard or custom groups claim available. |
|
|
|
JWK cache refresh interval in minutes. It is ignored unless the |
|
|
|
Forced JWK cache refresh interval in minutes, which is used to restrict the frequency of the forced refresh attempts that might happen when the token verification fails due to the cache having no JWK key with a |
|
|
|
Expiration grace in seconds. By default, an expired token is still accepted if the current time is no more than 1 min after the token expiry time. This property is deprecated. Use |
|
|
|
Comma-separated list of audiences a token |
|
|
| Comma-separated list of the claims a token must contain. |
|
|
|
Config property to specify the external or internal location of Private Decryption Key. This property is deprecated - use |
|
|
| Decryption algorithm. |
|
|
| Decryption key supplied as a string. |
|
|
|
Decryption Key identifier. If it is set then the decryption JWK key as well every JWT token must have a matching |
|
|
|
Path to TLS trusted certificate which might need to be configured if the keys have to be fetched over |
|
|
|
Trust all the hostnames. If the keys have to be fetched over |
|
|
|
Set of trusted hostnames. If the keys have to be fetched over |
|
|
| HTTP proxy host. |
|
|
| HTTP proxy port. |
|
|
|
This property can be used to customize a keystore type if either |
|
|
This property can be used to customize a | |
|
|
Keystore password. If | |
|
|
This property has to be set to identify a public verification key which is extracted from | |
|
|
This property has to be set to identify a private decryption key if | |
|
|
This property can be set if a private decryption key’s password in | |
|
|
| Set this property to true to resolve the remote keys at the application startup. |