Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit security-proactive-authentication.adoc #37851

Merged
merged 1 commit into from
Jan 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 25 additions & 22 deletions docs/src/main/asciidoc/security-proactive-authentication.adoc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

////
This document is maintained in the main Quarkus repository
and pull requests should be submitted there:
Expand All @@ -11,47 +12,48 @@
:topics: security,authentication
:extensions: io.quarkus:quarkus-vertx-http

Proactive authentication is enabled in Quarkus by default. This means that if an incoming request has a credential then that request will always be authenticated, even if the target page does not require authentication.

[[proactive-authentication]]

Requests with an invalid credential will always be rejected, even when the page is public.
Learn how to manage proactive authentication in Quarkus, including customizing settings and handling exceptions.
Gain practical insights and strategies for various application scenarios.

If you only want to authenticate when the target page requires authentication, you can change the default behavior.
Proactive authentication is enabled in Quarkus by default.
It ensures that all incoming requests with credentials are authenticated, even if the target page does not require authentication.
As a result, requests with invalid credentials are rejected, even if the target page is public.

To disable proactive authentication in Quarkus, set the following attribute in the `application.properties` configuration file:
You can turn off this default behavior if you want to authenticate only when the target page requires it.
To turn off proactive authentication so that authentication occurs only when the target page requires it, modify the `application.properties` configuration file as follows:

Check warning on line 23 in docs/src/main/asciidoc/security-proactive-authentication.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'because' or 'while' rather than 'as'.", "location": {"path": "docs/src/main/asciidoc/security-proactive-authentication.adoc", "range": {"start": {"line": 23, "column": 162}}}, "severity": "INFO"}

[source,xml,options="nowrap",role="white-space-pre"]
----
quarkus.http.auth.proactive=false
----

If you disable proactive authentication, the authentication process runs only when an identity is requested.
If you turn off proactive authentication, the authentication process runs only when an identity is requested.
An identity can be requested because of security rules that require the user to authenticate or because programmatic access to the current identity is required.

If proactive authentication is in use, accessing `SecurityIdentity` is a blocking operation.
This is because authentication might have yet to happen and accessing `SecurityIdentity` might require calls to external systems, such as databases, that might block the operation.
If proactive authentication is used, accessing `SecurityIdentity` is a blocking operation.
This is because authentication might have yet to happen, and accessing `SecurityIdentity` might require calls to external systems, such as databases, that might block the operation.

Check warning on line 34 in docs/src/main/asciidoc/security-proactive-authentication.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than ', that'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using ', which (non restrictive clause preceded by a comma)' or 'that (restrictive clause without a comma)' rather than ', that'.", "location": {"path": "docs/src/main/asciidoc/security-proactive-authentication.adoc", "range": {"start": {"line": 34, "column": 128}}}, "severity": "INFO"}
For blocking applications, this is not an issue.
However, if you have disabled authentication in a reactive application, this will fail because you cannot do blocking operations on the I/O thread.
However, if you have disabled authentication in a reactive application, this fails because you cannot do blocking operations on the I/O thread.
To work around this, you need to `@Inject` an instance of `io.quarkus.security.identity.CurrentIdentityAssociation` and call the `Uni<SecurityIdentity> getDeferredIdentity();` method.
Then, you can subscribe to the resulting `Uni` and will be notified when authentication is complete and the identity is available.
Then, you can subscribe to the resulting `Uni` to be notified when authentication is complete and the identity is available.

[NOTE]
====
You can still access `SecurityIdentity` synchronously with `public SecurityIdentity getIdentity()` in xref:resteasy-reactive.adoc[RESTEasy Reactive] from endpoints that are annotated with `@RolesAllowed`, `@Authenticated`, or with respective configuration authorization checks because authentication has already happened.
The same is also valid for xref:reactive-routes.adoc[Reactive routes] if a route response is synchronous.
====

xref:security-authorize-web-endpoints-reference.adoc#standard-security-annotations[Standard security annotations] on CDI beans are not supported on an I/O thread if a non-void secured method returns a value synchronously and proactive authentication is disabled because they need to access `SecurityIdentity`.
When proactive authentication is disabled, xref:security-authorize-web-endpoints-reference.adoc#standard-security-annotations[standard security annotations] used on CDI beans do not function on an I/O thread if a secured method that is not void synchronously returns a value.
This limitation arises from the necessity for these methods to access `SecurityIdentity`.

In the following example, `HelloResource` and `HelloService` are defined.
Any GET request to `/hello` will run on the I/O thread and throw a `BlockingOperationNotAllowedException` exception.
The following example defines `HelloResource` and `HelloService`.
Any GET request to `/hello` runs on the I/O thread and throws a `BlockingOperationNotAllowedException` exception.

There is more than one way to fix the example:

* Switch to a worker thread by annotating the `hello` endpoint with `@Blocking`.
* Change the `sayHello` method return type by using a reactive or asynchronous data type.
* Move `@RolesAllowed` annotation to the endpoint.
* Move the `@RolesAllowed` annotation to the endpoint.
This could be one of the safest ways because accessing `SecurityIdentity` from endpoint methods is never the blocking operation.

[source,java]
Expand Down Expand Up @@ -97,7 +99,8 @@
[[customize-auth-exception-responses]]
== Customize authentication exception responses

You can use Jakarta REST `ExceptionMapper` to capture Quarkus Security authentication exceptions such as `io.quarkus.security.AuthenticationFailedException`, for example:
You can use Jakarta REST `ExceptionMapper` to capture Quarkus Security authentication exceptions such as `io.quarkus.security.AuthenticationFailedException`.
For example:

[source,java]
----
Expand Down Expand Up @@ -125,12 +128,12 @@
}
----

CAUTION: Some HTTP authentication mechanisms need to handle authentication exceptions themselves to create a correct authentication challenge.
For example, `io.quarkus.oidc.runtime.CodeAuthenticationMechanism`, which manages OpenID Connect (OIDC) authorization code flow authentication, needs to build a correct redirect URL, cookies, and so on.
For that reason, avoid using custom exception mappers to customize authentication exceptions thrown by such mechanisms.
CAUTION: Some HTTP authentication mechanisms must handle authentication exceptions themselves to create a correct authentication challenge.
For example, `io.quarkus.oidc.runtime.CodeAuthenticationMechanism`, which manages OpenID Connect (OIDC) authorization code flow authentication, must build a correct redirect URL and set a state cookie.

Check warning on line 132 in docs/src/main/asciidoc/security-proactive-authentication.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using 'by using' or 'that uses' rather than 'using'.", "location": {"path": "docs/src/main/asciidoc/security-proactive-authentication.adoc", "range": {"start": {"line": 132, "column": 198}}}, "severity": "INFO"}
Therefore, avoid using custom exception mappers to customize authentication exceptions thrown by such mechanisms.
Instead, a safer approach is to ensure that proactive authentication is enabled and to use Vert.x HTTP route failure handlers.
This is because events come to the handler with the correct response status and headers.
You then only need to customize the response, as shown in the following example:
Then, you must only customize the response; for example:

[source,java]
----
Expand Down Expand Up @@ -167,4 +170,4 @@
* xref:security-overview.adoc[Quarkus Security overview]
* xref:security-architecture.adoc[Quarkus Security architecture]
* xref:security-authentication-mechanisms.adoc[Authentication mechanisms in Quarkus]
* xref:security-identity-providers.adoc[Identity providers]
* xref:security-identity-providers.adoc[Identity providers]