Skip to content

Commit

Permalink
Merge pull request #34360 from gsmet/3.2.0-backports-2
Browse files Browse the repository at this point in the history
3.2.0 backports 2
  • Loading branch information
gsmet authored Jun 28, 2023
2 parents 3027feb + 9a87ee4 commit 89b5342
Show file tree
Hide file tree
Showing 26 changed files with 491 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ private synchronized JarResult generateApplication() {
AugmentResult start = augmentAction.createProductionApplication();
if (!start.getJar().getType().equalsIgnoreCase(PackageConfig.BuiltInType.MUTABLE_JAR.getValue())) {
throw new RuntimeException(
"remote-dev can only be used with mutable applications generated with the fast-jar format");
"remote-dev can only be used with mutable applications i.e. " +
"using the mutable-jar package type");
}
//now extract the artifacts, to mirror the remote side
DevModeTask.extractDevModeClasses(start.getJar().getPath().getParent(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,8 @@ interface Debug {
interface Compression {
/**
* The compression level in [1, 10].
* 10 means <em>best</em>
*
* 10 means <em>best</em>.
* <p>
* Higher compression level requires more time to compress the executable.
*/
OptionalInt level();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.runtime.rest;

import java.util.List;
import java.util.Map;

/**
* This class serves for passing a list of disabled REST paths (via the `@EndpointDisabled` annotation)
* so that an OpenAPI filter can omit them from the generated OpenAPI document.
*/
public class DisabledRestEndpoints {

// keys are REST paths, values are HTTP methods disabled on the given path
private static Map<String, List<String>> endpoints;

public static void set(Map<String, List<String>> endpoints) {
DisabledRestEndpoints.endpoints = endpoints;
}

public static Map<String, List<String>> get() {
return endpoints;
}
}
2 changes: 1 addition & 1 deletion docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<properties>
<!-- The Graal version we suggest using in documentation - as that's
what we work with by self downloading it: -->
<graal-community.version-for-documentation>jdk-17.0.7</graal-community.version-for-documentation>
<graal-community.version-for-documentation>jdk-17</graal-community.version-for-documentation>
<mandrel.version-for-documentation>jdk-17</mandrel.version-for-documentation>

<assembly-maven-plugin.version>3.5.0</assembly-maven-plugin.version>
Expand Down
8 changes: 4 additions & 4 deletions docs/src/main/asciidoc/_attributes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// .
:maven-version: ${proposed-maven-version}
:graalvm-version: ${graal-community.version-for-documentation}
:graalvm-flavor: ${graal-community.version-for-documentation}-java17
:graalvm-flavor: ${graal-community.version-for-documentation}
:mandrel-version: ${mandrel.version-for-documentation}
:mandrel-flavor: ${mandrel.version-for-documentation}-java17
:mandrel-flavor: ${mandrel.version-for-documentation}
:surefire-version: ${version.surefire.plugin}
:gradle-version: ${gradle-wrapper.version}
:elasticsearch-version: ${elasticsearch-server.version}
Expand Down Expand Up @@ -53,9 +53,9 @@
:vault-guide: https://quarkiverse.github.io/quarkiverse-docs/quarkus-vault/dev/index.html
:vault-datasource-guide: https://quarkiverse.github.io/quarkiverse-docs/quarkus-vault/dev/vault-datasource.html
:micrometer-registry-guide: https://quarkiverse.github.io/quarkiverse-docs/quarkus-micrometer-registry/dev/index.html
:quarkus-migration-guide: https://github.com/quarkusio/quarkus/wiki/Migration-Guides
:quarkus-migration-guide: https://github.com/quarkusio/quarkus/wiki/Migration-Guides[Migration Guides]
// .
:create-app-group-id: org.acme
:create-cli-group-id: {create-app-group-id}
// .
include::_attributes-local.adoc[]
include::_attributes-local.adoc[]
48 changes: 29 additions & 19 deletions docs/src/main/asciidoc/building-native-image.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -122,36 +122,28 @@ On Windows, you will have to go through the Control Panel to set your environmen
====
Installing via scoop will do this for you.
====
3. (Only for GraalVM CE/EE) Install the `native-image` tool using `gu install`:
+
[source,bash]
----
${GRAALVM_HOME}/bin/gu install native-image
----
+
Some previous releases of GraalVM included the `native-image` tool by default. This is no longer the case; it must be installed as a second step after GraalVM itself is installed. Note: there is an outstanding issue xref:graal-and-catalina[using GraalVM with macOS Catalina].
4. (Optional) Set the `JAVA_HOME` environment variable to the GraalVM installation directory.
3. (Optional) Set the `JAVA_HOME` environment variable to the GraalVM installation directory.
+
[source,bash]
----
export JAVA_HOME=${GRAALVM_HOME}
----
5. (Optional) Add the GraalVM `bin` directory to the path
4. (Optional) Add the GraalVM `bin` directory to the path
+
[source,bash]
----
export PATH=${GRAALVM_HOME}/bin:$PATH
----

[[graal-and-catalina]]
.Issues using GraalVM with macOS Catalina
[[graal-and-macos]]
.Issues using GraalVM with macOS
[NOTE]
====
GraalVM binaries are not (yet) notarized for macOS Catalina as reported in this https://github.com/oracle/graal/issues/1724[GraalVM issue]. This means that you may see the following error when using `gu`:
GraalVM binaries are not (yet) notarized for macOS as reported in this https://github.com/oracle/graal/issues/1724[GraalVM issue]. This means that you may see the following error when using `native-image`:
[source,bash]
----
gu” cannot be opened because the developer cannot be verified
native-image” cannot be opened because the developer cannot be verified
----
Use the following command to recursively delete the `com.apple.quarantine` extended attribute on the GraalVM install directory as a workaround:
Expand Down Expand Up @@ -214,7 +206,7 @@ include::{includes}/devtools/build-native.adoc[]
====
The Microsoft Native Tools for Visual Studio must first be initialized before packaging. You can do this by starting
the `x64 Native Tools Command Prompt` that was installed with the Visual Studio Build Tools. At
`x64 Native Tools Command Prompt` you can navigate to your project folder and run `mvnw package -Dnative`.
`x64 Native Tools Command Prompt` you can navigate to your project folder and run `./mvnw package -Dnative`.
Another solution is to write a script to do this for you:
Expand Down Expand Up @@ -323,7 +315,9 @@ using the default, `prod` profile.
Alternatively, if you need to specify specific properties when running tests against the native executable
built using the `prod` profile, an option is to put those properties in file `src/test/resources/application-nativeit.yaml`, and refer to it from the `failsafe` plugin configuration using the `QUARKUS_CONFIG_LOCATIONS` environment variable. For instance:
```
[source,xml]
----
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
Expand All @@ -346,7 +340,7 @@ built using the `prod` profile, an option is to put those properties in file `sr
</execution>
</executions>
</plugin>
```
----
====

=== Java preview features
Expand Down Expand Up @@ -432,6 +426,17 @@ In this case, use the parameter `-Dquarkus.native.remote-container-build=true` i
The reason for this is that the local build driver invoked through `-Dquarkus.native.container-build=true` uses volume mounts to make the JAR available in the build container, but volume mounts do not work with remote daemons. The remote container build driver copies the necessary files instead of mounting them. Note that even though the remote driver also works with local daemons, the local driver should be preferred in the local case because mounting is usually more performant than copying.
====

[TIP]
====
The builder image used by default supports Java 17 as it is the latest LTS version.
If your application uses Java 18 or later, you need to specify a builder image supporting Java 20:
:build-additional-parameters: -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-20
include::{includes}/devtools/build-native-container-parameters.adoc[]
:!build-additional-parameters:
====

[TIP]
====
Building with GraalVM instead of Mandrel requires a custom builder image parameter to be passed additionally:
Expand Down Expand Up @@ -538,9 +543,14 @@ The project generation has also provided a `Dockerfile.native` in the `src/main/
----
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
----

Expand Down
4 changes: 3 additions & 1 deletion docs/src/main/asciidoc/management-interface-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ quarkus.management.enabled=true
----

By default, management endpoints will be exposed on: `http://0.0.0.0:9000/q`.
For example, `http://0.0.0.0:9000/q/health/ready` for the readiness probe.
For example, if you have `smallrye-health` installed, the readiness probe will be exposed at `http://0.0.0.0:9000/q/health/ready`.

SmallRye Health Checks, SmallRye Metrics, Micrometer and Info endpoints will be declared as management endpoints when the management interface is enabled.

NOTE: The management interface is disabled when no extensions relying on it (such as the SmallRye Health or SmallRye OpenAPI extensions) are installed.

== Configure the host, port and scheme

By default, the management interface is exposed on the interface: `0.0.0.0` (all interfaces) and on the port `9000` (`9001` in test mode).
Expand Down
26 changes: 26 additions & 0 deletions docs/src/main/asciidoc/native-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2235,3 +2235,29 @@ If the amount is not in hundreds, it could be a problem. A possible workaround i
export JAVA_OPTS=-Djava.security.egd=/dev/urandom
----
The proper solution is to increase the entropy available for the system. That is specific for each OS vendor and virtualization solution though.

=== Work around missing CPU features

When building on recent machines and running your native executable on older machines, you may see the following failure when starting the application:

[source]
----
The current machine does not support all of the following CPU features that are required by the image: [CX8, CMOV, FXSR, MMX, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, LZCNT, AVX, AVX2, BMI1, BMI2, FMA].
Please rebuild the executable with an appropriate setting of the -march option.
----

This error message means that the native compilation used more advanced instruction sets, not supported by the CPU running the application.
To work around that issue, add the following line to the `application.properties`:

[source, properties]
----
quarkus.native.additional-build-args=-march=compatibility
----

Then, rebuild your native executable.
This setting forces the native compilation to use an older instruction set, increasing the chance of compatibility.

To explicitly define the target architecture run `native-image -march=list` to get the supported configurations and then set `-march` to one of them, e.g., `quarkus.native.additional-build-args=-march=x86-64-v4`.
If you are targeting an AMD64 host, `-march=x86-64-v2` would work in most cases.

NOTE: The `march` parameter is only available on GraalVM 23+.
55 changes: 32 additions & 23 deletions docs/src/main/asciidoc/security-proactive-authentication.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,44 @@ Proactive authentication is enabled in Quarkus by default. This means that if an

[[proactive-authentication]]

Requests with an invalid credential will always be rejected, even when the page is public.
Requests with an invalid credential will always be rejected, even when the page is public.

You can change the default behavior if you only want to authenticate when the target page requires authentication.
If you only want to authenticate when the target page requires authentication, you can change the default behavior.

To disable proactive authentication in Quarkus, set the following attribute in the `application.properties` configuration file:
To disable proactive authentication in Quarkus, set the following attribute in the `application.properties` configuration file:

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

If you disable 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 you disable 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 the `SecurityIdentity` is a blocking operation.
This is because authentication may have yet to happen, and accessing it may require calls to external systems, such as databases that may block.
For blocking applications, this is no problem. However, if you have disabled authentication in a reactive application, this will fail (as you cannot do blocking operations on the IO thread).
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.
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.
To work around this, you need to `@Inject` an instance of `io.quarkus.security.identity.CurrentIdentityAssociation` and call the `Uni<SecurityIdentity> getDeferredIdentity();` method.
You can then 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` and will be notified when authentication is complete and the identity is available.

NOTE: It's still possible to access the `SecurityIdentity` synchronously with `public SecurityIdentity getIdentity()` in the xref:resteasy-reactive.adoc[RESTEasy Reactive] from endpoints annotated with `@RolesAllowed`, `@Authenticated`, 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.
[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-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.
xref:security-authorization.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`.

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.

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)
* arguably the safest way is to move `@RolesAllowed` annotation to the endpoint, as accessing `SecurityIdentity` from endpoint methods is never the blocking operation
* 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.
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 @@ -84,7 +92,7 @@ public class HelloService {
}
----

== How to customize authentication 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:

Expand Down Expand Up @@ -115,10 +123,11 @@ public class AuthenticationFailedExceptionMapper implements ExceptionMapper<Auth
----

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 authorization code flow authentication, needs to build a correct redirect URL, cookies, etc.
For that reason, using custom exception mappers to customize authentication exceptions thrown by such mechanisms is not recommended.
Instead, a safer approach would be 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 will then only need to customize the response, as outlined in the following example:
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.
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:

[source,java]
----
Expand Down Expand Up @@ -153,6 +162,6 @@ public class AuthenticationFailedExceptionHandler {
== References

* xref:security-overview.adoc[Quarkus Security overview]
* xref:security-architecture.adoc[Quarkus Security architecture]
* xref:security-authentication-mechanisms.adoc#other-supported-authentication-mechanisms[Authentication mechanisms in Quarkus]
* xref:security-architecture.adoc[Quarkus Security architecture]
* xref:security-authentication-mechanisms.adoc[Authentication mechanisms in Quarkus]
* xref:security-identity-providers.adoc[Identity providers]
Loading

0 comments on commit 89b5342

Please sign in to comment.