Skip to content

Commit

Permalink
Document RBAC used on CDI beans and IO thread when return is synchronous
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik committed Nov 14, 2022
1 parent 6ae8ff8 commit 696cb4a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/src/main/asciidoc/security-authorization.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ public class SubjectExposingResource {
<4> This call to obtain the user principal will return null if the caller is unauthenticated, non-null if the caller is authenticated.
<5> The `/subject/denied` endpoint disallows any access regardless of whether the call is authenticated by specifying the `@DenyAll` annotation.

CAUTION: Please refer to the xref:security-built-in-authentication.adoc#proactive-authentication[Proactive Authentication] section of the Built-In Authentication Support guide if you plan to use standard security annotations on IO thread.

== References

* xref:security.adoc[Quarkus Security]
49 changes: 49 additions & 0 deletions docs/src/main/asciidoc/security-built-in-authentication.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,55 @@ in the xref:resteasy-reactive.adoc[RESTEasy Reactive] from endpoints annotated w
or with respective configuration authorization checks as authentication has already happened. The same is also valid
for the xref:reactive-routes.adoc[Reactive routes] if a route response is synchronous.

xref:security-authorization.adoc#standard-security-annotations[Standard security annotations] on CDI beans are not supported on IO thread if a non-void secured method returns a value synchronously and proactive authentication is disabled, as they need to access the `SecurityIdentity`.
In the example below, we have defined `HelloResource` and `HelloService`. It's easy to see that any GET request to `/hello` will run on IO thread and throw `BlockingOperationNotAllowedException` exception.
There is more than one way to fix the example:

* switch to a worker thread (annotate `hello` endpoint with `@Blocking`)
* change `sayHello` method return type (use reactive or asynchronous data type)
* arguable the safest way is to move `@RolesAllowed` annotation to the endpoint, as accessing `SecurityIdentity` from endpoint methods is never the blocking operation

[source,java]
----
import javax.annotation.security.PermitAll;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import io.smallrye.mutiny.Uni;
@Path("/hello")
@PermitAll
public class HelloResource {
@Inject
HelloService helloService;
@GET
public Uni<String> hello() {
return Uni.createFrom().item(helloService.sayHello());
}
}
----

[source,java]
----
import javax.annotation.security.RolesAllowed;
import javax.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class HelloService {
@RolesAllowed("admin")
public String sayHello() {
return "Hello";
}
}
----


=== How to customize authentication exception responses

By default, the authentication security constraints are enforced before the JAX-RS chain starts and only way to handle Quarkus Security authentication exceptions is to provide a failure handler like this one:
Expand Down

0 comments on commit 696cb4a

Please sign in to comment.