Quarkus - Security Guide
Quarkus supports several sources to load authentication information from. You need to import at least one of the following extensionsin order for Quarkus to know how to find the authentication information to check for authorizations:
Please see the linked documents above for details on how to setup the various extensions.
Authenticating via HTTP
Quarkus has two built in authentication mechanisms for HTTP based FORM and BASIC auth. This mechanism is pluggablehowever so extensions can add additional mechanisms (most notably OpenID Connect for Keycloak based auth).
To enable basic authentication set quarkus.http.auth.basic=true
. You must also have at least one extension installedthat provides a username/password based IdentityProvider
, such as .
Form Based Authentication
Quarkus provides form based authentication that works in a similar manner to traditional Servlet form based auth. Unliketraditional form authentication the authenticated user is not stored in a HTTP session, as Quarkus does not provideclustered HTTP session support. Instead the authentication information is stored in an encrypted cookie, which canbe read by all members of the cluster (provided they all share the same encryption key).
The encryption key can be set using the quarkus.http.auth.session.encryption-key
property, and it must be at least 16 characterslong. This key is hashed using SHA-256 and the resulting digest is used as a key for AES-256 encryption of the cookievalue. This cookie contains a expiry time as part of the encrypted value, so all nodes in the cluster must have theirclocks synchronised. At one minute intervals a new cookie will be generated with an updated expiry time if the sessionis in use.
The following properties can be used to configure form based auth:
Configuration property fixed at build time - ️ Configuration property overridable at runtime
Configuration property | Type | Default |
---|---|---|
quarkus.http.auth.form.enabled If form authentication is enabled | boolean | false |
quarkus.http.auth.form.login-page The login page | string | /login.html |
quarkus.http.auth.form.error-page The error page | string | /error.html |
quarkus.http.auth.form.landing-page The landing page to redirect to if there is no saved page to redirect back to | string | required |
quarkus.http.auth.form.timeout The inactivity timeout | PT30M | |
quarkus.http.auth.form.new-cookie-interval How old a cookie can get before it will be replaced with a new cookie with an updated timeout. Not 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. | PT1M | |
quarkus.http.auth.form.cookie-name The cookie that is used to store the persistent session | string | quarkus-credential |
About the Duration formatThe format for durations uses the standard java.time.Duration format.You can learn more about it in the .You can also provide duration values starting with a number.In this case, if the value consists only of a number, the converter treats the value as seconds.Otherwise, PT is implicitly prepended to the value to obtain a standard java.time.Duration format. |
SubjectExposingResource Example
Authorization of Web Endpoints using configuration
Quarkus has an integrated plugable web security layer. If security is enabled all HTTP requests will have a permissioncheck performed to make sure they are permitted to continue.
Configuration authorization checks are executed before any annotation-based authorization check is done, so bothchecks have to pass for a request to be allowed. |
The default implementation allows you to define permissions using config in application.properties
. An exampleconfig is shown below:
quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin (1)
quarkus.http.auth.permission.roles1.paths=/roles-secured/*,/other/*,/api/* (2)
quarkus.http.auth.permission.roles1.policy=role-policy1
quarkus.http.auth.permission.permit1.paths=/public/* (3)
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET
quarkus.http.auth.permission.deny1.paths=/forbidden (4)
quarkus.http.auth.permission.deny1.policy=deny
1 | This defines a role based policy that allows users with the user and admin roles. This is referenced by later rules |
2 | This is a permission set that references the previously defined policy. roles1 is an arbitrary name, you can call the permission sets whatever you want. |
3 | This permission references the default permit built in policy to allow GET methods to /public . This is actually a no-op in this example, as this request would have been allowed anyway. |
4 | This permission references the built in deny build in policy /forbidden . This is an exact path match as it does not end with *. |
Permissions are defined in config using permission sets. These are arbitrarily named permission grouping. Each permissionset must specify a policy that is used to control access. There are three built in policies: deny
, permit
and authenticated
,which permit all, deny all and only allow authenticated users respectively.
It is also possible to define role based policies, as shown in the example. These policies will only allow users with thespecified roles to access the resources.
Permission sets can also specify paths and methods as a comma separated list. If a path ends with '*' then it is consideredto be a wildcard match and will match all sub paths, otherwise it is an exact match and will only match that specific path:
Matching path but not method
If a request would match one or more permission sets based on the path, but does not match any due to method requirementsthen the request is rejected.
Matching is always done on a longest path basis, less specific permission sets are not considered if a more specific onehas been matched:
quarkus.http.auth.permission.permit1.paths=/public/*
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.deny1.policy=deny
Given the above permission set, GET /public/forbidden-folder/foo would match both permission sets' paths,but because it matches the deny1 permission set’s path on a longer match, deny1 will be chosen and the request willbe rejected. |
Matching multiple paths: most specific method wins
Given the above permission set, GET /public/foo would match both permission sets' paths,but because it matches the permit1 permission set’s explicit method, permit1 will be chosen and the request willbe accepted. PUT /public/foo on the other hand, will not match the method permissions of permit1 and sodeny1 will be activated and reject the request. |
If multiple permission sets specify the same path and method (or multiple have no method) then both permissions have toallow access for the request to proceed. Note that for this to happen both have to either have specified the method, orhave no method, method specific matches take precedence as stated above:
quarkus.http.auth.policy.user-policy1.roles-allowed=user
quarkus.http.auth.policy.admin-policy1.roles-allowed=admin
quarkus.http.auth.permission.roles1.paths=/api/*,/restricted/*
quarkus.http.auth.permission.roles1.policy=user-policy1
quarkus.http.auth.permission.roles2.paths=/api/*,/admin/*
quarkus.http.auth.permission.roles2.policy=admin-policy1
For every authenticated resource, you can inject a SecurityIdentity
instance to get the authenticated identity information.
In some other contexts you may have other parallel representations of the same information (or parts of it) such as SecurityContext
for JAX-RS or JsonWebToken
for JWT.
Configuration
There are two configuration settings that alter the RBAC behavior:
quarkus.security.jaxrs.deny-unannotated-endpoints=true|false
- if set to true, the access will be denied for all JAX-RS endpoints by default.That is if the security annotations do not define the access control. Defaults tofalse
quarkus.security.deny-unannotated-members=true|false
- if set to true, the access will be denied to all CDI methodsand JAX-RS endpoints that do not have security annotations but are defined in classes that contain methods withsecurity annotations. Defaults tofalse
.
Registering Security Providers
When running in native mode the default behavior for Graal native image generation is to only include the main "SUN" providerunless you have enabled SSL, in which case all security providers are registered. If you are not using SSL, then you can selectivelyregister security providers by name using the quarkus.security.users.security-providers
property. The following example illustratesconfiguration to register the "SunRsaSign" and "SunJCE" security providers:
Example Security Providers Configuration