이 콘텐츠는 선택한 언어로 제공되지 않습니다.
Authorization of web endpoints
Abstract
Chapter 1. Authorization of web endpoints 링크 복사링크가 클립보드에 복사되었습니다!
Quarkus incorporates a pluggable web security layer. When security is active, the system performs a permission check on all HTTP requests to determine if they should proceed.
If you use Jakarta RESTful Web Services, consider using quarkus.security.jaxrs.deny-unannotated-endpoints or quarkus.security.jaxrs.default-roles-allowed to set default security requirements instead of HTTP path-level matching because annotations can override these properties on an individual endpoint.
Authorization is based on user roles that the security provider provides. To customize these roles, a SecurityIdentityAugmentor can be created, see Security Identity Customization.
1.1. Authorization using configuration 링크 복사링크가 클립보드에 복사되었습니다!
Permissions are defined in the Quarkus configuration by permission sets, each specifying a policy for access control.
When a security policy’s paths property contains the most specific path that matches the current request path, it takes precedence over other security policies with matching paths and is said to win.
| Built-in policy | Description |
|---|---|
|
| This policy denies all users. |
|
| This policy permits all users. |
|
| This policy permits only authenticated users. |
You can define role-based policies that allow users with specific roles to access the resources.
Example of a role-based policy
quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin
quarkus.http.auth.policy.role-policy1.roles-allowed=user,admin
- 1
- This defines a role-based policy that allows users with the
userandadminroles.
You can reference a custom policy by configuring the built-in permission sets that are defined in the application.properties file, as outlined in the following configuration example:
Example of policy configuration
- 1
- This permission references the default built-in
permitpolicy to allowGETmethods to/public. In this case, the demonstrated setting would not affect this example because this request is allowed anyway. - 2
- This permission references the built-in
denypolicy for both/forbiddenand/forbidden/paths. It is an exact path match because it does not end with*. - 3
- This permission set references the previously defined policy.
roles1is an example name; you can call the permission sets whatever you want.
The exact path pattern /forbidden in the example above also secures the /forbidden/ path. This way, the forbidden endpoint in the example below is secured by the deny1 permission.
- 1
- Both
/forbiddenand/forbidden/paths need to be secured in order to secure theforbiddenendpoint.
If you need to permit access to the /forbidden/ path, please add new permission with more specific exact path like in the example below:
quarkus.http.auth.permission.permit1.paths=/forbidden/ quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.paths=/forbidden/
quarkus.http.auth.permission.permit1.policy=permit
- 1
- The
/forbidden/path is not secured.
1.1.1. Custom HttpSecurityPolicy 링크 복사링크가 클립보드에 복사되었습니다!
Sometimes it might be useful to register your own named policy. You can get it done by creating application scoped CDI bean that implements the io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy interface like in the example below:
- 1
- Named HTTP Security policy will only be applied to requests matched by the
application.propertiespath matching rules.
Example of custom named HttpSecurityPolicy referenced from configuration file
quarkus.http.auth.permission.custom1.paths=/custom/* quarkus.http.auth.permission.custom1.policy=custom
quarkus.http.auth.permission.custom1.paths=/custom/*
quarkus.http.auth.permission.custom1.policy=custom
- 1
- Custom policy name must match the value returned by the
io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy.namemethod.
Alternatively, you can bind custom named HttpSecurityPolicy to Jakarta REST endpoints with the @AuthorizationPolicy security annotation.
You can also create global HttpSecurityPolicy invoked on every request. Just do not implement the io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy.name method and leave the policy nameless.
1.1.2. Inject @RequestScoped beans into HttpSecurityPolicy 링크 복사링크가 클립보드에 복사되었습니다!
@RequestScoped beans can only be injected when the CDI request context is active. The context can be activated by users, for example with the @ActivateRequestContext, however authorization happens before Quarkus prepares some @RequestScoped beans. We recommend to let Quarkus activate and prepare CDI request context for you. For example, consider a situation where you want to inject a bean from the Jakarta REST context, such as the jakarta.ws.rs.core.UriInfo bean. In this case, you must apply the HttpSecurityPolicy to Jakarta REST endpoints. This can be achieved in one of the following ways:
-
Use the
@AuthorizationPolicysecurity annotation. -
Set the
quarkus.http.auth.permission.custom1.applies-to=jaxrsconfiguration property.
1.1.3. Matching on paths and methods 링크 복사링크가 클립보드에 복사되었습니다!
Permission sets can also specify paths and methods as a comma-separated list. If a path ends with the * wildcard, the query it generates matches all sub-paths. Otherwise, it queries for an exact match and only matches that specific path:
quarkus.http.auth.permission.permit1.paths=/public*,/css/*,/js/*,/robots.txt quarkus.http.auth.permission.permit1.policy=permit quarkus.http.auth.permission.permit1.methods=GET,HEAD
quarkus.http.auth.permission.permit1.paths=/public*,/css/*,/js/*,/robots.txt
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET,HEAD
- 1
- The
*wildcard at the end of the path matches zero or more path segments, but never any word starting from the/publicpath. For that reason, a path like/public-infois not matched by this pattern.
1.1.4. Matching a path but not a method 링크 복사링크가 클립보드에 복사되었습니다!
The request is rejected if it matches one or more permission sets based on the path but none of the required methods.
Given the preceding permission set, GET /public/foo would match both the path and method and therefore be allowed. In contrast, POST /public/foo would match the path but not the method, and, therefore, be rejected.
1.1.5. Matching multiple paths: longest path wins 링크 복사링크가 클립보드에 복사되었습니다!
Matching is always done on the "longest path wins" basis. Less specific permission sets are not considered if a more specific one has been matched:
Given the preceding permission set, GET /public/forbidden-folder/foo would match both permission sets' paths. However, because the longer path matches the path of the deny1 permission set, deny1 is chosen, and the request is rejected.
Subpath permissions precede root path permissions, as the deny1 versus permit1 permission example previously illustrated.
This rule is further exemplified by a scenario where subpath permission allows access to a public resource while the root path permission necessitates authorization.
1.1.6. Matching multiple sub-paths: longest path to the * wildcard wins 링크 복사링크가 클립보드에 복사되었습니다!
Previous examples demonstrated matching all sub-paths when a path concludes with the * wildcard.
This wildcard can also be applied in the middle of a path, representing a single path segment. It cannot be mixed with other path segment characters; thus, path separators always enclose the * wildcard, as seen in the /public/*/about-us path.
When several path patterns correspond to the same request path, the system selects the longest sub-path leading to the * wildcard. In this context, every path segment character is more specific than the * wildcard.
Here is a simple example:
quarkus.http.auth.permission.secured.paths=/api/*/detail quarkus.http.auth.permission.secured.policy=authenticated quarkus.http.auth.permission.public.paths=/api/public-product/detail quarkus.http.auth.permission.public.policy=permit
quarkus.http.auth.permission.secured.paths=/api/*/detail
quarkus.http.auth.permission.secured.policy=authenticated
quarkus.http.auth.permission.public.paths=/api/public-product/detail
quarkus.http.auth.permission.public.policy=permit
All paths secured with the authorization using configuration should be tested. Writing path patterns with multiple wildcards can be cumbersome. Please make sure paths are authorized as you intended.
In the following example, paths are ordered from the most specific to the least specific one:
Request path /one/two/three/four/five matches ordered from the most specific to the least specific path
The * wildcard at the end of the path matches zero or more path segments. The * wildcard placed anywhere else matches exactly one path segment.
1.1.7. Matching multiple paths: most specific method wins 링크 복사링크가 클립보드에 복사되었습니다!
When a path is registered with multiple permission sets, the permission sets explicitly specifying an HTTP method that matches the request take precedence. In this instance, the permission sets without methods only come into effect if the request method does not match permission sets with the method specification.
The preceding permission set shows that GET /public/foo matches the paths of both permission sets.However, it specifically aligns with the explicit method of the permit1 permission set.Therefore, permit1 is selected, and the request is accepted.
In contrast, PUT /public/foo does not match the method permissions of permit1. As a result, deny1 is activated, leading to the rejection of the request.
1.1.8. Matching multiple paths and methods: both win 링크 복사링크가 클립보드에 복사되었습니다!
Sometimes, the previously described rules allow multiple permission sets to win simultaneously. In that case, for the request to proceed, all the permissions must allow access. For this to happen, both must either have specified the method or have no method. Method-specific matches take precedence.
Given the preceding permission set, GET /api/foo would match both permission sets' paths, requiring both the user and admin roles.
1.1.9. Configuration properties to deny access 링크 복사링크가 클립보드에 복사되었습니다!
The following configuration settings alter the role-based access control (RBAC) denying behavior:
quarkus.security.jaxrs.deny-unannotated-endpoints=true|false-
If set to true, access is denied for all Jakarta REST endpoints by default. If a Jakarta REST endpoint has no security annotations, it defaults to the
@DenyAllbehavior. This helps you to avoid accidentally exposing an endpoint that is supposed to be secured. Defaults tofalse. quarkus.security.jaxrs.default-roles-allowed=role1,role2-
Defines the default role requirements for unannotated endpoints. The
**role is a special role that means any authenticated user. This cannot be combined withdeny-unannotated-endpointsbecausedenytakes effect instead. quarkus.security.deny-unannotated-members=true|false-
If set to true, the access is denied to all CDI methods and Jakarta REST endpoints that do not have security annotations but are defined in classes that contain methods with security annotations. Defaults to
false.
1.1.10. Disabling permissions 링크 복사링크가 클립보드에 복사되었습니다!
Permissions can be disabled at build time with an enabled property for each declared permission, such as:
quarkus.http.auth.permission.permit1.enabled=false quarkus.http.auth.permission.permit1.paths=/public/*,/css/*,/js/*,/robots.txt quarkus.http.auth.permission.permit1.policy=permit quarkus.http.auth.permission.permit1.methods=GET,HEAD
quarkus.http.auth.permission.permit1.enabled=false
quarkus.http.auth.permission.permit1.paths=/public/*,/css/*,/js/*,/robots.txt
quarkus.http.auth.permission.permit1.policy=permit
quarkus.http.auth.permission.permit1.methods=GET,HEAD
Permissions can be reenabled at runtime with a system property or environment variable, such as: -Dquarkus.http.auth.permission.permit1.enabled=true.
1.1.11. Permission paths and HTTP root path 링크 복사링크가 클립보드에 복사되었습니다!
The quarkus.http.root-path configuration property changes the http endpoint context path.
By default, quarkus.http.root-path is prepended automatically to configured permission paths then do not use a forward slash, for example:
quarkus.http.auth.permission.permit1.paths=public/*,css/*,js/*,robots.txt
quarkus.http.auth.permission.permit1.paths=public/*,css/*,js/*,robots.txt
This configuration is equivalent to the following:
quarkus.http.auth.permission.permit1.paths=${quarkus.http.root-path}/public/*,${quarkus.http.root-path}/css/*,${quarkus.http.root-path}/js/*,${quarkus.http.root-path}/robots.txt
quarkus.http.auth.permission.permit1.paths=${quarkus.http.root-path}/public/*,${quarkus.http.root-path}/css/*,${quarkus.http.root-path}/js/*,${quarkus.http.root-path}/robots.txt
A leading slash changes how the configured permission path is interpreted. The configured URL is used as-is, and paths are not adjusted if the value of quarkus.http.root-path changes.
Example:
quarkus.http.auth.permission.permit1.paths=/public/*,css/*,js/*,robots.txt
quarkus.http.auth.permission.permit1.paths=/public/*,css/*,js/*,robots.txt
This configuration only impacts resources served from the fixed or static URL, /public, which might not match your application resources if quarkus.http.root-path has been set to something other than /.
For more information, see Path Resolution in Quarkus.
1.1.12. Map SecurityIdentity roles 링크 복사링크가 클립보드에 복사되었습니다!
The winning role-based policy that was chosen to authorize the current request can map SecurityIdentity roles to deployment-specific roles. These roles are then applicable for endpoint authorization by using the @RolesAllowed annotation.
quarkus.http.auth.policy.admin-policy1.roles.admin=Admin1 quarkus.http.auth.permission.roles1.paths=/* quarkus.http.auth.permission.roles1.policy=admin-policy1
quarkus.http.auth.policy.admin-policy1.roles.admin=Admin1
quarkus.http.auth.permission.roles1.paths=/*
quarkus.http.auth.permission.roles1.policy=admin-policy1
If all that you need is to map the SecurityIdentity roles to the deployment-specific roles regardless of a path, you can also do this:
quarkus.http.auth.roles-mapping.admin=Admin1
quarkus.http.auth.roles-mapping.admin=Admin1
If you prefer a programmatic configuration, the same mapping can be added with the io.quarkus.vertx.http.security.HttpSecurity CDI event:
1.1.14. Set up path-specific authorization programmatically 링크 복사링크가 클립보드에 복사되었습니다!
You can also configure the authorization policies presented by this guide so far programmatically. Consider the example mentioned earlier:
The same authorization policies can be configured programmatically:
Additionally, the io.quarkus.vertx.http.security.HttpSecurity CDI event can be used to configure specific authentication mechanisms and policies:
- 1
- Use the Basic authentication and authorize the requests with a custom
io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy. - 2
- Use the Bearer token authentication and authorize the
SecurityIdentitywith your own policy. - 3
- Use Authorization Code Flow mechanism and write your own policy based on incoming request headers.
- 4
- When Quarkus fires the
HttpSecurityCDI event, the runtime configuration is ready. - 5
- Require that all the requests to the
/user-infopath have string permissionsopenid,emailandprofile. The same authorization can be required with the@PermissionsAllowed(value = { "openid", "email", "profile" }, inclusive = true)annotation instance placed on an endpoint.
1.1.14.1. Programmatic set up references 링크 복사링크가 클립보드에 복사되었습니다!
1.2. Authorization using annotations 링크 복사링크가 클립보드에 복사되었습니다!
Quarkus includes built-in security to allow for Role-Based Access Control (RBAC) based on the common security annotations @RolesAllowed, @DenyAll, @PermitAll on REST endpoints and CDI beans.
Authorization checks for quarkus.http.auth. configurations are performed before security checks for standard security annotations. Therefore, @PermitAll only permits access to paths that are not already restricted by HTTP permissions. @PermitAll cannot override HTTP-level security configurations, only relax restrictions imposed by other standard security annotations such as @RolesAllowed.
| Annotation type | Description |
|---|---|
|
| Specifies that no security roles are allowed to invoke the specified methods. |
|
| Specifies that all security roles are allowed to invoke the specified methods.
|
|
| Specifies the list of security roles allowed to access methods in an application. |
|
|
Quarkus provides the |
|
| Specifies the list of permissions that are allowed to invoke the specified methods. |
|
|
Specifies named |
The following SubjectExposingResource example demonstrates an endpoint that uses both Jakarta REST and Common Security annotations to describe and secure its endpoints.
SubjectExposingResource example
- 1
- The
/subject/securedendpoint requires an authenticated user with the granted "Tester" role through the use of the@RolesAllowed("Tester")annotation. - 2
- The endpoint obtains the user principal from the Jakarta REST
SecurityContext. This returnsnon-nullfor a secured endpoint. - 3
- The
/subject/authenticatedendpoint allows any authenticated user by specifying the@Authenticatedannotation. - 4
- The
/subject/unsecuredendpoint allows for unauthenticated access by specifying the@PermitAllannotation. - 5
- The call to obtain the user principal returns
nullif the caller is unauthenticated andnon-nullif the caller is authenticated. - 6
- The
/subject/deniedendpoint declares the@DenyAllannotation, disallowing all direct access to it as a REST method, regardless of the user calling it. The method is still invokable internally by other methods in this class.
If you plan to use standard security annotations on the IO thread, review the information in Proactive Authentication.
The @RolesAllowed annotation value supports property expressions including default values and nested property expressions. Configuration properties used with the annotation are resolved at runtime.
| Annotation | Value explanation |
|---|---|
|
|
The endpoint allows users with the role denoted by the value of the |
|
| An example showing that the value can contain multiple variables. |
|
|
A default value demonstration. The required role is denoted by the value of the |
Example of a property expressions usage in the @RolesAllowed annotation
Subject access control example
- 1
- The
@RolesAllowedannotation value is set to the value ofAdministrator. - 2
- This
/subject/software-testerendpoint requires an authenticated user that has been granted the role of "Software-Tester". It is possible to use multiple expressions in the role definition. - 3
- This
/subject/userendpoint requires an authenticated user that has been granted the role "User" through the use of the@RolesAllowed("${customer:User}")annotation because we did not set the configuration propertycustomer. - 4
- In production, this
/subject/securedendpoint requires an authenticated user with theUserrole. In development mode, it allows any authenticated user. - 5
- Property expression
all-roleswill be treated as a collection typeList, therefore, the endpoint will be accessible for rolesAdministrator,Software,TesterandUser.
1.2.1. Endpoint security annotations and Jakarta REST inheritance 링크 복사링크가 클립보드에 복사되었습니다!
Quarkus supports security annotations placed on the endpoint implementation or its class like in the example below:
The RESTEasy subresource locators declared as default interface methods cannot be secured by standard security annotations. Secured subresource locators must be implemented and secured on the interface implementors like in the example below:
1.2.2. Permission annotation 링크 복사링크가 클립보드에 복사되었습니다!
Quarkus also provides the io.quarkus.security.PermissionsAllowed annotation, which authorizes any authenticated user with the given permission to access the resource. This annotation is an extension of the common security annotations and checks the permissions granted to a SecurityIdentity instance.
Example of endpoints secured with the @PermissionsAllowed annotation
- 1
- The resource method
createOrUpdateis only accessible for a user with bothcreateandupdatepermissions. - 2
- By default, at least one of the permissions specified through one annotation instance is required. You can require all permissions by setting
inclusive=true. Both resource methodscreateOrUpdatehave equal authorization requirements. - 3
- Access is granted to
getItemifSecurityIdentityhas eitherreadpermission orseepermission and one of theallordetailactions. - 4
- You can use your preferred
java.security.Permissionimplementation. By default, string-based permission is performed byio.quarkus.security.StringPermission. - 5
- Permissions are not beans, therefore the only way to obtain bean instances is programmatically by using
Arc.container().
If you plan to use the @PermissionsAllowed on the IO thread, review the information in Proactive Authentication.
@PermissionsAllowed is not repeatable on the class level due to a limitation with Quarkus interceptors. For more information, see the Repeatable interceptor bindings section of the Quarkus "CDI reference" guide.
The easiest way to add permissions to a role-enabled SecurityIdentity instance is to map roles to permissions. Use Authorization using configuration to grant the required SecurityIdentity permissions for CRUDResource endpoints to authenticated requests, as outlined in the following example:
- 1
- Add the permission
seeand the actionallto theSecurityIdentityinstance of theuserrole. Similarly, for the@PermissionsAllowedannotation,io.quarkus.security.StringPermissionis used by default. - 2
- Permissions
create,update, andreadare mapped to the roleadmin. - 3
- The role policy
role-policy1allows only authenticated requests to access/crud/modifyand/crud/idsub-paths. For more information about the path-matching algorithm, see Matching multiple paths: longest path wins later in this guide. - 4
- You can specify a custom implementation of the
java.security.Permissionclass. Your custom class must define exactly one constructor that accepts the permission name and optionally some actions, for example,Stringarray. In this scenario, the permissionlistis added to theSecurityIdentityinstance asnew CustomPermission("list").
You can also create a custom java.security.Permission class with additional constructor parameters. These additional parameters names get matched with arguments names of the method annotated with the @PermissionsAllowed annotation. Later, Quarkus instantiates your custom permission with actual arguments, with which the method annotated with the @PermissionsAllowed has been invoked.
Example of a custom java.security.Permission class that accepts additional arguments
- 1
- There must be exactly one constructor of a custom
Permissionclass. The first parameter is always considered to be a permission name and must be of typeString. Quarkus can optionally pass permission actions to the constructor. For this to happen, declare the second parameter asString[].
The LibraryPermission class permits access to the current or parent library if SecurityIdentity is allowed to perform one of the required actions, for example, read, write, or list.
The following example shows how the LibraryPermission class can be used:
- 1
- The formal parameter
libraryis identified as the parameter matching same-namedLibraryPermissionconstructor parameter. Therefore, Quarkus will pass thelibraryparameter to theLibraryPermissionclass constructor. However, theLibraryPermissionmust be instantiated each time theupdateLibrarymethod is invoked. - 2
- Here, the second
Libraryparameter matches the namelibrary, while themigrateparameter is ignored during theLibraryPermissionpermission instantiation.
Example of a resource secured with the LibraryPermission
Similarly to the CRUDResource example, the following example shows how you can grant a user with the admin role permissions to update MediaLibrary:
- 1
- When building a native executable, the permission class must be registered for reflection unless it is also used in at least one
io.quarkus.security.PermissionsAllowed#nameparameter. More details about the@RegisterForReflectionannotation can be found on the native application tips page. - 2
- We want to pass the
MediaLibraryinstance to theLibraryPermissionconstructor.
quarkus.http.auth.policy.role-policy3.permissions.admin=media-library:list,media-library:read,media-library:write quarkus.http.auth.policy.role-policy3.permission-class=org.acme.library.MediaLibraryPermission quarkus.http.auth.permission.roles3.paths=/library/* quarkus.http.auth.permission.roles3.policy=role-policy3
quarkus.http.auth.policy.role-policy3.permissions.admin=media-library:list,media-library:read,media-library:write
quarkus.http.auth.policy.role-policy3.permission-class=org.acme.library.MediaLibraryPermission
quarkus.http.auth.permission.roles3.paths=/library/*
quarkus.http.auth.permission.roles3.policy=role-policy3
- 1
- Grants the permission
media-library, which permitsread,write, andlistactions. BecauseMediaLibraryis theTvLibraryclass parent, a user with theadminrole is also permitted to modifyTvLibrary.
The /library/* path can be tested from a Keycloak provider Dev UI page, because the user alice which is created automatically by the Dev Services for Keycloak has an admin role.
The examples provided so far demonstrate role-to-permission mapping. It is also possible to programmatically add permissions to the SecurityIdentity instance. In the following example, SecurityIdentity is customized to add the same permission that was previously granted with the HTTP role-based policy.
Example of adding the LibraryPermission programmatically to SecurityIdentity
- 1
- Add a
media-librarypermission that was created can performread,write, andlistactions. BecauseMediaLibraryis theTvLibraryclass parent, a user with theadminrole is also permitted to modifyTvLibrary.
Annotation-based permissions do not work with custom Jakarta REST SecurityContexts because there are no permissions in jakarta.ws.rs.core.SecurityContext.
1.2.2.1. Create permission checkers 링크 복사링크가 클립보드에 복사되었습니다!
By default, SecurityIdentity must be configured with permissions which can be used to check if this identity passes @PermissionAllowed authorization restrictions. Alternatively, you can use a @PermissionChecker annotation to mark any CDI bean method as a permission checker. The @PermissionChecker annotation value should match required permission declared by the @PermissionsAllowed annotation value. For example, a permission checker can be created like this:
- 1
- The permission required to access the
ProjectResource#renameProjectis therename-projectpermission. - 2
- The
ProjectResource#canRenameProjectmethod authorizes access to theProjectResource#renameProjectendpoint. - 3
- The
SecurityIdentityinstance can be injected into any permission checker method. - 4
- In this example, the
rename-projectpermission checker is declared on the same resource. However, there is no restriction on where this permission checker can be declared as demonstrated in the next example.
Permission checker methods can be declared on a normal scoped CDI bean or on a @Singleton bean. The @Dependent CDI bean scope is currently not supported.
The permission checker above requires the SecurityIdentity instance to authorize the renameProject endpoint. Instead of declaring the rename-project permission checker directly on the resource, you can declare it on any CDI bean like in this example:
Permission checks run by default on event loops. Annotate a permission checker method with the io.smallrye.common.annotation.Blocking annotation if you want to run the check on a worker thread.
Matching between the @PermissionsAllowed values and the @PermissionChecker value is based on string equality as shown in the example below:
1.2.2.2. Create permission meta-annotations 링크 복사링크가 클립보드에 복사되었습니다!
@PermissionsAllowed can also be used in meta-annotations. For example, a new @CanWrite security annotation can be created like this:
- 1
- Any method or class annotated with the
@CanWriteannotation is secured with this@PermissionsAllowedannotation instance.
1.2.2.3. Pass @BeanParam parameters into a custom permission 링크 복사링크가 클립보드에 복사되었습니다!
Quarkus can map fields of a secured method parameters to a custom permission constructor parameters. You can use this feature to pass jakarta.ws.rs.BeanParam parameters into your custom permission. Let’s consider following Jakarta REST resource:
- 1
- The
paramsannotation attribute specifies that user principal name should be passed to theBeanParamPermissionChecker#canSayHellomethod. OtherBeanParamPermissionChecker#canSayHellomethod parameters likecustomAuthorizationHeaderandqueryare matched automatically. Quarkus identifies theBeanParamPermissionChecker#canSayHellomethod parameters amongbeanParamfields and their public accessors. To avoid ambiguous resolution, automatic detection only works for thebeanParamfields. For that reason, we had to specify path to the user principal name explicitly.
Where the SimpleBeanParam class is declared like in the example below:
- 1
- Quarkus Security can only pass public fields to a custom permission constructor.
- 2
- Quarkus Security automatically uses public getter methods if they are available.
- 3
- The
customAuthorizationHeaderfield is not public, therefore Quarkus access this field with thecustomAuthorizationHeaderaccessor. That is particularly useful with Java records, where generated accessors are not prefixed withget.
Here is an example of a @PermissionChecker method that checks the say-hello permission based on a user principal, custom header and query parameter:
You can pass @BeanParam directly into a @PermissionChecker method and access its fields programmatically. Ability to reference @BeanParam fields with the @PermissionsAllowed#params attribute is useful when you have multiple differently structured @BeanParam classes.