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

Migrate to Quarkiverse Docs from main README #493

Merged
merged 16 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
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
832 changes: 2 additions & 830 deletions README.md

Large diffs are not rendered by default.

163 changes: 163 additions & 0 deletions docs/modules/ROOT/pages/includes/authentication-support.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
If your OpenAPI specification file has `securitySchemes` https://spec.openapis.org/oas/v3.1.0#security-scheme-object[definitions], the inner generator
will https://download.eclipse.org/microprofile/microprofile-rest-client-2.0/microprofile-rest-client-spec-2.0.html#_provider_declaration[register ClientRequestFilter providers] for you to
implement the given authentication mechanism.

To provide the credentials for your application, you can use the https://quarkus.io/guides/config[Quarkus configuration support]. The configuration key is composed using this
pattern: `quarkus.openapi-generator.[filename].auth.[security_scheme_name].[auth_property_name]`. Where:

* `filename` is the sanitized name of file containing the OpenAPI spec, for example `petstore_json`.
* `security_scheme_name` is the sanitized name of the https://spec.openapis.org/oas/v3.1.0#security-scheme-object[security scheme object definition] in the OpenAPI file. Given the following excerpt, we
have `api_key` and `basic_auth` security schemes:

[source,json]
----
{
"securitySchemes": {
"api_key": {
"type": "apiKey",
"name": "api_key",
"in": "header"
},
"basic_auth": {
"type": "http",
"scheme": "basic"
}
}
}
----

WARNING: Note that the securityScheme name used to configure the specific information for each spec is sanitized using the same rules as for the file names.

* `auth_property_name` varies depending on the authentication provider. For example, for Basic Authentication we have `username` and `password`. See the following sections for more details.

> Tip: on production environments you will likely to use https://quarkiverse.github.io/quarkiverse-docs/quarkus-vault/dev/index.html[HashiCorp Vault] or https://kubernetes.io/docs/concepts/configuration/secret/[Kubernetes Secrets] to provide this information for your application.

If the OpenAPI specification file has `securitySchemes` definitions, but no https://spec.openapis.org/oas/v3.1.0#security-requirement-object[Security Requirement Object] definitions, the generator can be configured to create these by default. In this case, for all operations without a security requirement the default one will be created. Note that the property value needs to match the name of a security scheme object definition, eg. `api_key` or `basic_auth` in the `securitySchemes` list above.


[%autowidth]
|===
|Description |Property Key |Example

|Create security for the referenced security scheme
|`quarkus.openapi-generator.codegen.default-security-scheme`
|`quarkus.openapi-generator.codegen.default-security-scheme=api_key`
|===

See the module https://github.com/quarkiverse/quarkus-openapi-generator/tree/main/integration-tests/security[security] for an example of how to use this feature.

== Basic HTTP Authentication

For Basic HTTP Authentication, these are the supported configurations:

[%autowidth]
|===
|Description |Property Key |Example

|Username credentials
|`quarkus.openapi-generator.[filename].auth.[security_scheme_name].username`
| `quarkus.openapi-generator.petstore_json.auth.basic_auth.username`
|Password credentials
|`quarkus.openapi-generator.[filename].auth.[security_scheme_name].password`
|`quarkus.openapi-generator.petstore_json.auth.basic_auth-password`
|===

== Bearer Token Authentication

Authentication, these are the supported configurations:

[%autowidth]
|===
|Description |Property Key |Example

|Bearer Token
|`quarkus.openapi-generator.[filename].auth.[security_scheme_name].bearer-token`
|`quarkus.openapi-generator.petstore_json.auth.bearer.bearer-token`
|===

== API Key Authentication

Similarly to bearer token, the API Key Authentication also has the token entry key property:

[%autowidth]
|===
|Description |Property Key |Example

|API Key
|`quarkus.openapi-generator.[filename].auth.[security_scheme_name].api-key`
|`quarkus.openapi-generator.petstore_json.auth.api_key.api-key`
|===

The API Key scheme has an additional property that requires where to add the API key in the request token: header, cookie or query. The inner provider takes care of that for you.

== OAuth2 Authentication

The extension will generate a `ClientRequestFilter` capable to add OAuth2 authentication capabilities to the OpenAPI operations that require it. This means that you can use
the https://quarkus.io/guides/security-openid-connect-client[Quarkus OIDC Extension] configuration to define your authentication flow.

The generated code creates a named `OidcClient` for each https://spec.openapis.org/oas/v3.1.0#security-scheme-object[Security Scheme] listed in the OpenAPI specification files. For example, given
the following excerpt:

[source,json]
----
{
"securitySchemes": {
"petstore_auth": {
"type": "oauth2",
"flows": {
"implicit": {
"authorizationUrl": "https://petstore3.swagger.io/oauth/authorize",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
}
}
}
}
}
----

You can configure this `OidcClient` as:

[source,properties]
----
quarkus.oidc-client.petstore_auth.auth-server-url=https://petstore3.swagger.io/oauth/authorize
quarkus.oidc-client.petstore_auth.discovery-enabled=false
quarkus.oidc-client.petstore_auth.token-path=/tokens
quarkus.oidc-client.petstore_auth.credentials.secret=secret
quarkus.oidc-client.petstore_auth.grant.type=password
quarkus.oidc-client.petstore_auth.grant-options.password.username=alice
quarkus.oidc-client.petstore_auth.grant-options.password.password=alice
quarkus.oidc-client.petstore_auth.client-id=petstore-app
----

The configuration suffix `quarkus.oidc-client.petstore_auth` is exclusive for the schema defined in the specification file and the `schemaName` is sanitized by applying the rules described above.

For this to work you **must** add https://quarkus.io/guides/security-openid-connect-client#oidc-client-filter[Quarkus OIDC Client Filter Extension] to your project:

RESTEasy Classic:

[source ,xml]
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc-client-filter</artifactId>
</dependency>
----

RESTEasy Reactive:

[source ,xml]
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-oidc-client-reactive-filter</artifactId>
</dependency>
----

If authentication support doesn't suit your needs you can decide to disable it with `enable-security-generation=false`. In such case CompositeAuthenticationProvider and AuthenticationPropagationHeadersFactory wont be generated and used with your api.
The option can be set globally with `quarkus.openapi-generator.codegen.enable-security-generation` or per api `quarkus.openapi-generator.codegen.spec.my_spec_yml.enable-security-generation`
Custom authentication provider can be used with `additional-api-type-annotations`

See the module https://github.com/quarkiverse/quarkus-openapi-generator/tree/main/integration-tests/generation-tests[generation-tests] for an example of how to use this feature.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
The authorization token propagation can be used with OpenApi operations secured with a security scheme of type "oauth2" or "bearer".
When configured, you can propagate the authorization tokens passed to your service and the invocations to the REST clients generated by the quarkus-openapi-generator.

Let's see how it works by following a simple example:

Imagine that we have a `updatePet` operation defined in the `petstore.json` specification file and secured with the `petstore_auth` security scheme.
The code below shows a simple example of the usage of this operation in a user-programmed service.

[source ,java]
----
import org.acme.api.PetApi;
import org.acme.model.Pet;
import org.eclipse.microprofile.rest.client.inject.RestClient;

/**
* User programmed service.
*/
@Path("/petstore")
public class PetResource {

/**
* Inject the rest client generated by the quarkus-openapi-generator.
*/
@Inject
@RestClient
PetApi petApi;

/**
* User programmed operation.
*/
@Path("/pet/{id}")
@PATCH
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response customUpdatePet(@PathParam("id") long id, PetData petData) {

// Create a new instance of the Pet class generated by the quarkus-openapi-generator and
// populate accordingly.
Pet pet = new Pet();
pet.setId(id);
applyDataToPet(pet, petData);

// Execute the rest call using the generated client.
// The petstore.json open api spec stays that the "updatePet" operation is secured with the
// security scheme "petstore_auth".
petApi.updatePet(pet);

// Do other required things and finally return something.
return Response.ok().build();
}

public static class PetData {
// Represents the Pet modifiable data sent to the user programmed service.
}

private void applyDataToPet(Pet pet, PetData petData) {
// Set the corresponding values to the Pet instance.
}
}
----

Let's see what happens when the PetResource service `customUpdatePet` operation is invoked by a third party.

== Default flow

. The `customUpdatePet` operation is invoked.
. An authorization token is obtained using the corresponding `petstore_auth` OidcClient configuration. (for more information see <<_oauth2_authentication>>)
. The authorization token is automatically passed along the PetApi `updatePet` operation execution using an automatically generated request filter, etc.

=== Propagation flow

However, there are scenarios where we want to propagate the authorization token that was initially passed to the PetResource service when the `customUpdatePet` operation was invoked instead of having to obtain it by using the `OidcClient`.

. The user service `customUpdatePet` operation is invoked, and an authorization token is passed by the third party typically by using the HTTP `Authorization` header.
. The incoming authorization token is automatically passed along the PetApi `updatePet` operation execution according to the user-provided configuration.

WARNING: When configured, the token propagation applies to all the operations secured with the same `securityScheme` in the same specification file.

=== Propagation flow configuration

The token propagation can be used with type "oauth2" or "bearer" security schemes. Finally, considering that a given security scheme might be configured on a set of operations in the same specification file when configured, it'll apply to all these operations.

[%autowidth]
|===
|Property Key |Example

|`quarkus.openapi-generator.[filename].auth.[security_scheme_name].token-propagation=[true,false]`
|`quarkus.openapi-generator.petstore_json.auth.petstore_auth.token-propagation=true` +
Enables the token propagation for all the operations that are secured with the `petstore_auth` scheme in the `petstore_json` file.
|`quarkus.openapi-generator.[filename].auth.[security_scheme_name].header-name=[http_header_name]`
|`quarkus.openapi-generator.petstore_json.auth.petstore_auth.header-name=MyHeaderName` +
Says that the authorization token to propagate will be read from the HTTP header `MyHeaderName` instead of the standard HTTP `Authorization` header.
|===
123 changes: 123 additions & 0 deletions docs/modules/ROOT/pages/includes/circuit-breaker.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@

You can define the https://microprofile.io/project/eclipse/microprofile-fault-tolerance/spec/src/main/asciidoc/circuitbreaker.asciidoc[CircuitBreaker annotation from MicroProfile Fault Tolerance]
in your generated classes by setting the desired configuration in `application.properties`.

Let's say you have the following OpenAPI definition:

[source ,json]
----
{
"openapi": "3.0.3",
"info": {
"title": "Simple API",
"version": "1.0.0-SNAPSHOT"
},
"paths": {
"/hello": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/bye": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
}
}
}
}
}
}
----

And you want to configure Circuit Breaker for the `/bye` endpoint, you can do it in the following way:

Add the https://quarkus.io/guides/smallrye-fault-tolerance[SmallRye Fault Tolerance extension] to your project's `pom.xml` file:

[source ,xml]
----
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-fault-tolerance</artifactId>
</dependency>
----

Assuming your Open API spec file is in `src/main/openapi/simple-openapi.json`, add the following configuration to your `application.properties` file:

[source ,properties]
----
# Note that the file name must have only alphabetic characters or underscores (_).
quarkus.openapi-generator.codegen.spec.simple_openapi_json.base-package=org.acme.openapi.simple
# Enables the CircuitBreaker extension for the byeGet method from the DefaultApi class
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/enabled=true
----

With the above configuration, your Rest Clients will be created with a code similar to the following:

[source ,java]
----
package org.acme.openapi.simple.api;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.MediaType;

@Path("")
@RegisterRestClient(configKey="simple-openapi_json")
public interface DefaultApi {

@GET
@Path("/bye")
@Produces({ "text/plain" })
@org.eclipse.microprofile.faulttolerance.CircuitBreaker
public String byeGet();

@GET
@Path("/hello")
@Produces({ "text/plain" })
public String helloGet();

}
----

You can also override the default Circuit Breaker configuration by setting the properties
in `application.properties` https://quarkus.io/guides/smallrye-fault-tolerance#runtime-configuration[just as you would for a traditional MicroProfile application]:

[source ,properties]
----
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/failOn=java.lang.IllegalArgumentException,java.lang.NullPointerException
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/skipOn=java.lang.NumberFormatException
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/delay=33
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/delayUnit=MILLIS
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/requestVolumeThreshold=42
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/failureRatio=3.14
org.acme.openapi.simple.api.DefaultApi/byeGet/CircuitBreaker/successThreshold=22
----

See the module https://github.com/quarkiverse/quarkus-openapi-generator/tree/main/integration-tests/circuit-breaker[circuit-breaker] for an example of how to use this feature.
Loading