Authentication mechanisms in Quarkus
The Quarkus Security framework supports multiple authentication mechanisms, which you can use to secure your applications. You can also combine authentication mechanisms.
Before you choose an authentication mechanism for securing your Quarkus applications, review the information provided. |
Overview of supported authentication mechanisms
Some supported authentication mechanisms are built into Quarkus, while others require you to add an extension. All of these mechanisms are detailed in the following sections:
The following table maps specific authentication requirements to a supported mechanism that you can use in Quarkus:
Authentication requirement | Authentication mechanism |
---|---|
Username and password |
|
Bearer access token |
|
Single sign-on (SSO) |
|
Client certificate |
|
WebAuthn |
|
Kerberos ticket |
For more information, see the following Token authentication mechanism comparison table.
Built-in authentication mechanisms
Quarkus Security provides the following built-in authentication support:
Basic authentication
You can secure your Quarkus application endpoints with the built-in HTTP Basic authentication mechanism. For more information, see the following documentation:
Form-based authentication
Quarkus provides form-based authentication that works similarly to traditional Servlet form-based auth. Unlike traditional form authentication, the authenticated user is not stored in an HTTP session because Quarkus does not support clustered HTTP sessions. Instead, the authentication information is stored in an encrypted cookie, which can be read by all cluster members who share the same encryption key.
To apply encryption, add the quarkus.http.auth.session.encryption-key
property, and ensure the value you set is at least 16 characters long. The
encryption key is hashed by using SHA-256. The resulting digest is used as
a key for AES-256 encryption of the cookie value. The cookie contains an
expiry time as part of the encrypted value, so all nodes in the cluster must
have their clocks synchronized. At one-minute intervals, a new cookie gets
generated with an updated expiry time if the session is in use.
With single-page applications (SPA), you typically want to avoid redirects by removing default page paths, as shown in the following example:
# do not redirect, respond with HTTP 200 OK
quarkus.http.auth.form.landing-page=
# do not redirect, respond with HTTP 401 Unauthorized
quarkus.http.auth.form.login-page=
quarkus.http.auth.form.error-page=
# HttpOnly must be false if you want to logout on the client, it can be true if logging out on from the server
quarkus.http.auth.form.http-only-cookie=false
Now that you have disabled redirects for the SPA, you must login and logout
programmatically from your client. Below are example JavaScript methods for
logging into the j_security_check
endpoint and logging out of the
application by destroying the cookie.
const login = () => {
// Create an object to represent the form data
const formData = new URLSearchParams();
formData.append("j_username", username);
formData.append("j_password", password);
// Make an HTTP POST request using fetch against j_security_check endpoint
fetch("j_security_check", {
method: "POST",
body: formData,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
.then((response) => {
if (response.status === 200) {
// Authentication was successful
console.log("Authentication successful");
} else {
// Authentication failed
console.error("Invalid credentials");
}
})
.catch((error) => {
console.error(error);
});
};
To logout of the SPA from the client the cookie must be set to
quarkus.http.auth.form.http-only-cookie=false
so you can destroy the
cookie and possibly redirect back to your main page.
const logout= () => {
// delete the credential cookie essentially killing the session
const removeCookie = `quarkus-credential=; Max-Age=0;path=/`;
document.cookie = removeCookie;
// perform post logout actions here such as redirecting back to your login page
};
To logout of the SPA from the server the cookie can be set to
quarkus.http.auth.form.http-only-cookie=true
and use this example code to
destroy the cookie.
@ConfigProperty(name = "quarkus.http.auth.form.cookie-name")
String cookieName;
@Inject
CurrentIdentityAssociation identity;
@POST
public Response logout() {
if (identity.getIdentity().isAnonymous()) {
throw new UnauthorizedException("Not authenticated");
}
final NewCookie removeCookie = new NewCookie.Builder(cookieName)
.maxAge(0)
.expiry(Date.from(Instant.EPOCH))
.path("/")
.build();
return Response.noContent().cookie(removeCookie).build();
}
The following properties can be used to configure form-based authentication:
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
If form authentication is enabled. Environment variable: Show more |
boolean |
|
The post location. Environment variable: Show more |
string |
|
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
The authentication realm Environment variable: Show more |
string |
|
The login page. Redirect to login page can be disabled by setting Environment variable: Show more |
string |
|
The username field name. Environment variable: Show more |
string |
|
The password field name. Environment variable: Show more |
string |
|
The error page. Redirect to error page can be disabled by setting Environment variable: Show more |
string |
|
The landing page to redirect to if there is no saved page to redirect back to. Redirect to landing page can be disabled by setting Environment variable: Show more |
string |
|
Option to control the name of the cookie used to redirect the user back to where he wants to get access to. Environment variable: Show more |
string |
|
The inactivity (idle) timeout When inactivity timeout is reached, cookie is not renewed and a new login is enforced. Environment variable: Show more |
|
|
How old a cookie can get before it will be replaced with a new cookie with an updated timeout, also referred to as "renewal-timeout". Note that smaller values will result in slightly more server load (as new encrypted cookies will be generated more often), however larger values affect the inactivity timeout as the timeout is set when a cookie is generated. For example if this is set to 10 minutes, and the inactivity timeout is 30m, if a users last request is when the cookie is 9m old then the actual timeout will happen 21m after the last request, as the timeout is only refreshed when a new cookie is generated. In other words no timeout is tracked on the server side; the timestamp is encoded and encrypted in the cookie itself, and it is decrypted and parsed with each request. Environment variable: Show more |
|
|
The cookie that is used to store the persistent session Environment variable: Show more |
string |
|
The cookie path for the session and location cookies. Environment variable: Show more |
string |
|
Set the HttpOnly attribute to prevent access to the cookie via JavaScript. Environment variable: Show more |
boolean |
|
SameSite attribute for the session and location cookies. Environment variable: Show more |
|
|
Determines whether the entire permission set is enabled, or not. By default, if the permission set is defined, it is enabled. Environment variable: Show more |
boolean |
|
The HTTP policy that this permission set is linked to. There are 3 built in policies: permit, deny and authenticated. Role based policies can be defined, and extensions can add their own policies. Environment variable: Show more |
string |
required |
The methods that this permission set applies to. If this is not set then they apply to all methods. Note that if a request matches any path from any permission set, but does not match the constraint due to the method not being listed then the request will be denied. Method specific permissions take precedence over matches that do not have any methods set. This means that for example if Quarkus is configured to allow GET and POST requests to /admin to and no other permissions are configured PUT requests to /admin will be denied. Environment variable: Show more |
list of string |
|
The paths that this permission check applies to. If the path ends in /* then this is treated as a path prefix, otherwise it is treated as an exact match. Matches are done on a length basis, so the most specific path match takes precedence. If multiple permission sets match the same path then explicit methods matches take precedence over matches without methods set, otherwise the most restrictive permissions are applied. Environment variable: Show more |
list of string |
|
Path specific authentication mechanism which must be used to authenticate a user. It needs to match Environment variable: Show more |
string |
|
The roles that are allowed to access resources protected by this policy. By default, access is allowed to any authenticated user. Environment variable: Show more |
list of string |
|
Permissions granted to the Environment variable: Show more |
|
|
Permissions granted by this policy will be created with a Environment variable: Show more |
string |
|
About the Duration format
To write duration values, use the standard You can also use a simplified format, starting with a number:
In other cases, the simplified format is translated to the
|
Mutual TLS authentication
Quarkus provides mutual TLS (mTLS) authentication so that you can authenticate users based on their X.509 certificates.
To use this authentication method, you must first enable SSL/TLS for your application. For more information, see the Supporting secure connections with SSL section of the Quarkus "HTTP reference" guide.
After your application accepts secure connections, the next step is to
configure the quarkus.http.ssl.certificate.trust-store-file
property with
the name of that file that holds all the certificates your application
trusts. The specified file also includes information about how your
application asks for certificates when a client, such as a browser or other
service, tries to access one of its protected resources.
quarkus.http.ssl.certificate.key-store-file=server-keystore.jks (1)
quarkus.http.ssl.certificate.key-store-password=the_key_store_secret
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks (2)
quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret
quarkus.http.ssl.client-auth=required (3)
quarkus.http.auth.permission.default.paths=/* (4)
quarkus.http.auth.permission.default.policy=authenticated
1 | The keystore where the server’s private key is located. |
2 | The truststore from which the trusted certificates are loaded. |
3 | With this value set to required , the server requires certificates from
clients. To relax this requirement so that the server accepts requests
without a certificate, set the value to REQUEST . This option is useful
when you are also supporting authentication methods other than mTLS. |
4 | Defines a policy where only authenticated users should have access to resources from your application. |
When the incoming request matches a valid certificate in the truststore,
your application can obtain the subject by injecting a SecurityIdentity
as
follows:
@Inject
SecurityIdentity identity;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return String.format("Hello, %s", identity.getPrincipal().getName());
}
You can also get the certificate by using the code outlined in the following example:
import java.security.cert.X509Certificate;
import io.quarkus.security.credential.CertificateCredential;
CertificateCredential credential = identity.getCredential(CertificateCredential.class);
X509Certificate certificate = credential.getCertificate();
Authorization
The information from the client certificate can be used to enhance Quarkus
SecurityIdentity
. For example, you can add new roles after checking a
client certificate subject name, and so on. For more information about
customizing SecurityIdentity
, see the
Security
identity customization section in the Quarkus "Security tips and tricks"
guide.
Other supported authentication mechanisms
Quarkus Security also supports the following authentication mechanisms through extensions:
WebAuthn authentication
WebAuthn is an authentication mechanism that replaces passwords. When you write a service for registering new users, or logging them in, instead of asking for a password, you can use WebAuthn, which replaces the password. For more information, see the Secure a Quarkus application by using the WebAuthn authentication mechanism guide.
OpenID Connect authentication
OpenID Connect (OIDC) is an identity layer that works on top of the OAuth 2.0 protocol. OIDC enables client applications to verify the identity of a user based on the authentication performed by the OIDC provider and retrieve basic information about that user.
The Quarkus quarkus-oidc
extension provides a reactive, interoperable,
multitenant-enabled OIDC adapter that supports Bearer token and
Authorization Code Flow authentication mechanisms. The Bearer token
authentication mechanism extracts the token from the HTTP Authorization
header. The Authorization Code Flow mechanism redirects the user to an OIDC
provider to authenticate the user’s identity. After the user is redirected
back to Quarkus, the mechanism completes the authentication process by
exchanging the provided code that was granted for the ID, access, and
refresh tokens.
You can verify ID and access JSON Web Token (JWT) tokens by using the refreshable JSON Web Key (JWK) set or introspect them remotely. However, opaque, also known as binary tokens, can only be introspected remotely.
Using the Quarkus OIDC extension, both the Bearer token and Authorization
Code Flow authentication mechanisms use
SmallRye JWT authentication to represent
JWT tokens as MicroProfile JWT |
Additional Quarkus resources for OIDC authentication
For more information about OIDC authentication and authorization methods that you can use to secure your Quarkus applications, see the following resources:
OIDC topic | Quarkus information resource |
---|---|
Bearer token authentication mechanism |
|
Authorization Code Flow authentication mechanism |
|
OIDC and SAML Identity broker |
OpenID Connect (OIDC) Authorization Code Flow and SAML Identity broker |
Multiple tenants that can support the Bearer token authentication or Authorization Code Flow mechanisms |
|
Securing Quarkus with commonly-used OpenID Connect providers |
|
Using Keycloak to centralize authorization |
Using OpenID Connect (OIDC) and Keycloak to centralize authorization |
Configuring Keycloak programmatically |
To enable the Quarkus OIDC extension at runtime, set
For more information about managing the individual tenant configurations in multitenant OIDC deployments, see the Disabling tenant configurations section in the "Using OpenID Connect (OIDC) multi-tenancy" guide. |
OpenID Connect client and filters
The quarkus-oidc-client
extension provides OidcClient
for acquiring and
refreshing access tokens from OpenID Connect and OAuth2 providers that
support the following token grants:
-
client-credentials
-
password
-
refresh_token
The quarkus-oidc-client-filter
extension requires the
quarkus-oidc-client
extension. It provides JAX-RS RESTful Web Services
OidcClientRequestFilter
, which sets the access token acquired by
OidcClient
as the Bearer
scheme value of the HTTP Authorization
header. This filter can be registered with MicroProfile REST client
implementations injected into the current Quarkus endpoint, but it is not
related to the authentication requirements of this service endpoint. For
example, it can be a public endpoint or be protected with mTLS.
In this scenario, you do not need to protect your Quarkus endpoint by using the Quarkus OpenID Connect adapter. |
The quarkus-oidc-token-propagation
extension requires the quarkus-oidc
extension. It provides Jakarta REST TokenCredentialRequestFilter
, which
sets the OpenID Connect Bearer token or Authorization Code Flow access token
as the Bearer
scheme value of the HTTP Authorization
header. This
filter can be registered with MicroProfile REST client implementations
injected into the current Quarkus endpoint, which must be protected by using
the Quarkus OIDC adapter. This filter can propagate the access token to the
downstream services.
For more information, see the OpenID Connect client and token propagation quickstart and OpenID Connect (OIDC) and OAuth2 client and filters reference guides.
SmallRye JWT authentication
The quarkus-smallrye-jwt
extension provides a MicroProfile JSON Web Token
(JWT) 2.1 implementation and multiple options to verify signed and encrypted
JWT
tokens. It represents them as
org.eclipse.microprofile.jwt.JsonWebToken
.
quarkus-smallrye-jwt
is an alternative to the quarkus-oidc
Bearer token
authentication mechanism and verifies only JWT
tokens by using either
Privacy Enhanced Mail (PEM) keys or the refreshable JWK
key set.
quarkus-smallrye-jwt
also provides the JWT generation API, which you can
use to easily create signed
, inner-signed
, and encrypted
JWT
tokens.
For more information, see the Using JWT RBAC guide.
OAuth2 authentication
quarkus-elytron-security-oauth2
provides an alternative to the Quarkus
quarkus-oidc
Bearer token authentication mechanism extension.
quarkus-elytron-security-oauth2
is based on Elytron
and is primarily
intended for introspecting opaque tokens remotely. For more information,
see the Quarkus Using OAuth2 guide.
Choosing between OpenID Connect, SmallRye JWT, and OAuth2 authentication mechanisms
Use the following information to select the appropriate token authentication mechanism to secure your Quarkus applications.
-
quarkus-oidc
requires an OpenID Connect provider such as Keycloak, which can verify the bearer tokens or authenticate the end users with the Authorization Code flow. In both cases,quarkus-oidc
requires a connection to the specified OpenID Connect provider. -
If the user authentication requires Authorization Code flow, or you need to support multiple tenants, use
quarkus-oidc
.quarkus-oidc
can also request user information by using both Authorization Code Flow and Bearer access tokens. -
If your bearer tokens must be verified, use
quarkus-oidc
,quarkus-smallrye-jwt
, orquarkus-elytron-security-oauth2
. -
If your bearer tokens are in a JSON web token (JWT) format, you can use any extensions in the preceding list. Both
quarkus-oidc
andquarkus-smallrye-jwt
support refreshing theJsonWebKey
(JWK) set when the OpenID Connect provider rotates the keys. Therefore, if remote token introspection must be avoided or is unsupported by the providers, usequarkus-oidc
orquarkus-smallrye-jwt
for verifying JWT tokens. -
To introspect the JWT tokens remotely, you can use either
quarkus-oidc
orquarkus-elytron-security-oauth2
because they support verifying the opaque or binary tokens by using remote introspection.quarkus-smallrye-jwt
does not support the remote introspection of both opaque or JWT tokens but instead relies on the locally available keys that are usually retrieved from the OpenID Connect provider. -
quarkus-oidc
andquarkus-smallrye-jwt
support the JWT and opaque token injection into the endpoint code. Injected JWT tokens provide more information about the user. All extensions can have the tokens injected asPrincipal
. -
quarkus-smallrye-jwt
supports more key formats thanquarkus-oidc
.quarkus-oidc
uses only the JWK-formatted keys that are part of a JWK set, whereasquarkus-smallrye-jwt
supports PEM keys. -
quarkus-smallrye-jwt
handles locally signed, inner-signed-and-encrypted, and encrypted tokens. In contrast, althoughquarkus-oidc
andquarkus-elytron-security-oauth2
can also verify such tokens, they treat them as opaque tokens and verify them through remote introspection. -
If you need a lightweight library for the remote introspection of opaque or JWT tokens, use
quarkus-elytron-security-oauth2
.
Architectural considerations drive your decision to use opaque or JSON web token (JWT) token format. Opaque tokens tend to be much shorter than JWT tokens but need most of the token-associated state to be maintained in the provider database. Opaque tokens are effectively database pointers. JWT tokens are significantly longer than opaque tokens. Nonetheless, the providers effectively delegate most of the token-associated state to the client by storing it as the token claims and either signing or encrypting them. |
Feature required |
Authentication mechanism |
||
|
|
|
|
Bearer JWT verification |
Local verification or introspection |
Local verification |
Introspection |
Bearer opaque token verification |
Introspection |
No |
Introspection |
Refreshing |
Yes |
Yes |
No |
Represent token as |
Yes |
Yes |
Yes |
Inject JWT as MP JWT |
Yes |
Yes |
No |
Authorization code flow |
Yes |
No |
No |
Multi-tenancy |
Yes |
No |
No |
User information support |
Yes |
No |
No |
PEM key format support |
No |
Yes |
No |
SecretKey support |
No |
In JSON Web Key (JWK) format |
No |
Inner-signed and encrypted or encrypted tokens |
Introspection |
Local verification |
Introspection |
Custom token verification |
No |
With injected JWT parser |
No |
JWT as a cookie support |
No |
Yes |
Yes |
Combining authentication mechanisms
If different sources provide the user credentials, you can combine
authentication mechanisms. For example, you can combine the built-in Basic
and the Quarkus quarkus-oidc
Bearer token authentication mechanisms.
You cannot combine the Quarkus |
Path-specific authentication mechanisms
The following configuration example demonstrates how you can enforce a single selectable authentication mechanism for a given request path:
quarkus.http.auth.permission.basic-or-bearer.paths=/service
quarkus.http.auth.permission.basic-or-bearer.policy=authenticated
quarkus.http.auth.permission.basic.paths=/basic-only
quarkus.http.auth.permission.basic.policy=authenticated
quarkus.http.auth.permission.basic.auth-mechanism=basic
quarkus.http.auth.permission.bearer.paths=/bearer-only
quarkus.http.auth.permission.bearer.policy=authenticated
quarkus.http.auth.permission.bearer.auth-mechanism=bearer
Ensure that the value of the auth-mechanism
property matches the
authentication scheme supported by HttpAuthenticationMechanism
, for
example, basic
, bearer
, or form
.
Proactive authentication
Proactive authentication is enabled in Quarkus by default. This means that if an incoming request has a credential, the request will always be authenticated, even if the target page does not require authentication. For more information, see the Quarkus Proactive authentication guide.