Skip to content

Commit eaa8a2e

Browse files
committed
Add OpenIdConnectAuthenticationMarker
1 parent 97d49d3 commit eaa8a2e

File tree

5 files changed

+100
-7
lines changed

5 files changed

+100
-7
lines changed

client/deployment/src/main/java/io/quarkiverse/openapi/generator/deployment/GeneratorProcessor.java

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@
2222
import io.quarkiverse.openapi.generator.OidcClient;
2323
import io.quarkiverse.openapi.generator.OpenApiGeneratorConfig;
2424
import io.quarkiverse.openapi.generator.OpenApiSpec;
25-
import io.quarkiverse.openapi.generator.markers.ApiKeyAuthenticationMarker;
26-
import io.quarkiverse.openapi.generator.markers.BasicAuthenticationMarker;
27-
import io.quarkiverse.openapi.generator.markers.BearerAuthenticationMarker;
28-
import io.quarkiverse.openapi.generator.markers.OauthAuthenticationMarker;
29-
import io.quarkiverse.openapi.generator.markers.OperationMarker;
25+
import io.quarkiverse.openapi.generator.markers.*;
3026
import io.quarkiverse.openapi.generator.oidc.ClassicOidcClientRequestFilterDelegate;
3127
import io.quarkiverse.openapi.generator.oidc.OidcAuthenticationRecorder;
3228
import io.quarkiverse.openapi.generator.oidc.ReactiveOidcClientRequestFilterDelegate;
@@ -51,6 +47,8 @@ public class GeneratorProcessor {
5147

5248
private static final String FEATURE = "openapi-generator";
5349
private static final DotName OAUTH_AUTHENTICATION_MARKER = DotName.createSimple(OauthAuthenticationMarker.class);
50+
private static final DotName OPEN_ID_CONNECT_AUTHENTICATION_MARKER = DotName
51+
.createSimple(OpenIdConnectAuthenticationMarker.class);
5452
private static final DotName BASIC_AUTHENTICATION_MARKER = DotName.createSimple(BasicAuthenticationMarker.class);
5553
private static final DotName BEARER_AUTHENTICATION_MARKER = DotName.createSimple(BearerAuthenticationMarker.class);
5654
private static final DotName API_KEY_AUTHENTICATION_MARKER = DotName.createSimple(ApiKeyAuthenticationMarker.class);
@@ -185,6 +183,68 @@ void produceOauthAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
185183
}
186184
}
187185

186+
@BuildStep
187+
@Record(ExecutionTime.RUNTIME_INIT)
188+
void produceOpenIdConnectAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,
189+
BuildProducer<AuthProviderBuildItem> authenticationProviders,
190+
BuildProducer<SyntheticBeanBuildItem> beanProducer,
191+
OidcAuthenticationRecorder oidcRecorder) {
192+
193+
Collection<AnnotationInstance> authenticationMarkers = beanArchiveBuildItem.getIndex()
194+
.getAnnotationsWithRepeatable(OPEN_ID_CONNECT_AUTHENTICATION_MARKER, beanArchiveBuildItem.getIndex())
195+
.stream()
196+
.collect(Collectors.toMap(
197+
AnnotationInstance::equivalenceHashCode,
198+
marker -> marker,
199+
(existing, duplicate) -> existing))
200+
.values();
201+
202+
if (!isClassPresentAtRuntime(ABSTRACT_TOKEN_PRODUCER)) {
203+
if (!authenticationMarkers.isEmpty()) {
204+
throw new IllegalStateException(
205+
"OAuth2 flows detected in spec(s) " +
206+
authenticationMarkers.stream()
207+
.map(m -> m.value("openApiSpecId").asString())
208+
.distinct()
209+
.collect(Collectors.joining(", "))
210+
+
211+
" but quarkus-openapi-generator-oidc and quarkus-rest-client-oidc-filter or quarkus-oidc-client-reactive-filter are not on the classpath. "
212+
+
213+
"Please add those dependencies to your project. See https://docs.quarkiverse.io/quarkus-openapi-generator/dev/client.html#_oauth2_authentication");
214+
}
215+
LOGGER.debug("{} class not found in runtime, skipping OAuth bean generation", ABSTRACT_TOKEN_PRODUCER);
216+
return;
217+
}
218+
LOGGER.debug("{} class found in runtime, producing OAuth bean generation", ABSTRACT_TOKEN_PRODUCER);
219+
220+
Map<String, List<AnnotationInstance>> operationsBySpec = getOperationsBySpec(beanArchiveBuildItem);
221+
222+
for (AnnotationInstance authenticationMarker : authenticationMarkers) {
223+
String name = authenticationMarker.value("name").asString();
224+
String openApiSpecId = authenticationMarker.value("openApiSpecId").asString();
225+
List<OperationAuthInfo> operations = getOperations(operationsBySpec, openApiSpecId, name);
226+
authenticationProviders.produce(new AuthProviderBuildItem(openApiSpecId, name));
227+
beanProducer.produce(SyntheticBeanBuildItem.configure(AuthProvider.class)
228+
.scope(Dependent.class)
229+
.addQualifier()
230+
.annotation(AuthName.class)
231+
.addValue("name", name)
232+
.done()
233+
.addQualifier()
234+
.annotation(OpenApiSpec.class)
235+
.addValue("openApiSpecId", openApiSpecId)
236+
.done()
237+
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
238+
.addInjectionPoint(ClassType.create(OAuth2AuthenticationProvider.OidcClientRequestFilterDelegate.class),
239+
AnnotationInstance.builder(OidcClient.class).add("name", sanitizeAuthName(name)).build())
240+
.addInjectionPoint(ClassType.create(DotName.createSimple(CredentialsProvider.class)))
241+
.createWith(oidcRecorder.recordOauthAuthProvider(sanitizeAuthName(name), openApiSpecId, operations))
242+
.setRuntimeInit()
243+
.unremovable()
244+
.done());
245+
}
246+
}
247+
188248
@BuildStep
189249
@Record(ExecutionTime.RUNTIME_INIT)
190250
void produceBasicAuthentication(CombinedIndexBuildItem beanArchiveBuildItem,

client/deployment/src/main/resources/templates/libraries/microprofile/auth/compositeAuthenticationProvider.qute

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ package {apiPackage}.auth;
44
{#for auth in openapi:getUniqueOAuthOperations(oauthMethods.orEmpty)}
55
@io.quarkiverse.openapi.generator.markers.OauthAuthenticationMarker(name="{auth.name}", openApiSpecId="{quarkus-generator.openApiSpecId}")
66
{/for}
7+
{#for auth in openapi:getUniqueOAuthOperations(openIdConnectMethods.orEmpty)}
8+
@io.quarkiverse.openapi.generator.markers.OpenIdConnectAuthenticationMarker(name="{auth.name}", openApiSpecId="{quarkus-generator.openApiSpecId}")
9+
{/for}
710
{#for auth in httpBasicMethods.orEmpty}
811
@io.quarkiverse.openapi.generator.markers.BasicAuthenticationMarker(name="{auth.name}", openApiSpecId="{quarkus-generator.openApiSpecId}")
912
{/for}

client/integration-tests/auth-provider/src/main/resources/application.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ quarkus.oidc-client.service5_oauth2.credentials.client-secret.value=secret
4444

4545
# Oidc client used by the token_external_service6
4646
quarkus.oidc-client.service6_oidc.auth-server-url=${keycloak.mock.service.url}
47-
quarkus.oidc-client.service6_oidc.discovery-enabled=true
47+
quarkus.oidc-client.service6_oidc.token-path=${keycloak.mock.service.token-path}
48+
quarkus.oidc-client.service6_oidc.discovery-enabled=false
4849
quarkus.oidc-client.service6_oidc.client-id=kogito-app
4950
quarkus.oidc-client.service6_oidc.grant.type=client
5051
quarkus.oidc-client.service6_oidc.credentials.client-secret.method=basic

client/integration-tests/security/src/main/resources/application.properties

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ quarkus.openapi-generator.codegen.spec.token_propagation_external_service2_yaml.
3232
quarkus.openapi-generator.codegen.spec.token_propagation_external_service3_yaml.base-package=org.acme.externalservice3
3333
quarkus.openapi-generator.codegen.spec.token_propagation_external_service4_yaml.base-package=org.acme.externalservice4
3434
quarkus.openapi-generator.codegen.spec.token_propagation_external_service5_yaml.base-package=org.acme.externalservice5
35+
quarkus.openapi-generator.codegen.spec.token_propagation_external_service6_yaml.base-package=org.acme.externalservice6
3536

3637
quarkus.rest-client.token_propagation_external_service1_yaml.url=${propagation-external-service-mock.url}
3738
quarkus.rest-client.token_propagation_external_service2_yaml.url=${propagation-external-service-mock.url}
3839
quarkus.rest-client.token_propagation_external_service3_yaml.url=${propagation-external-service-mock.url}
3940
quarkus.rest-client.token_propagation_external_service4_yaml.url=${propagation-external-service-mock.url}
4041
quarkus.rest-client.token_propagation_external_service5_yaml.url=${propagation-external-service-mock.url}
42+
quarkus.rest-client.token_propagation_external_service6_yaml.url=${propagation-external-service-mock.url}
43+
4144

4245
# default propagation for token_propagation_external_service1 invocation
4346
quarkus.openapi-generator.token_propagation_external_service1_yaml.auth.service1_http_bearer.token-propagation=true
@@ -80,7 +83,8 @@ quarkus.oidc-client.service5_oauth2.credentials.client-secret.value=secret
8083

8184
# Oidc client used by the token_propagation_external_service6
8285
quarkus.oidc-client.service6_oidc.auth-server-url=${keycloak.mock.service.url}
83-
quarkus.oidc-client.service6_oidc.discovery-enabled=true
86+
quarkus.oidc-client.service6_oidc.token-path=${keycloak.mock.service.token-path}
87+
quarkus.oidc-client.service6_oidc.discovery-enabled=false
8488
quarkus.oidc-client.service6_oidc.client-id=kogito-app
8589
quarkus.oidc-client.service6_oidc.grant.type=client
8690
quarkus.oidc-client.service6_oidc.credentials.client-secret.method=basic
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.quarkiverse.openapi.generator.markers;
2+
3+
import static java.lang.annotation.ElementType.TYPE;
4+
5+
import java.lang.annotation.Repeatable;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
@Target(TYPE)
11+
@Retention(RetentionPolicy.RUNTIME)
12+
@Repeatable(OpenIdConnectAuthenticationMarker.AuthenticationMarkers.class)
13+
public @interface OpenIdConnectAuthenticationMarker {
14+
15+
String name();
16+
17+
String openApiSpecId();
18+
19+
@Target(TYPE)
20+
@Retention(RetentionPolicy.RUNTIME)
21+
@interface AuthenticationMarkers {
22+
OpenIdConnectAuthenticationMarker[] value();
23+
}
24+
25+
}

0 commit comments

Comments
 (0)