diff --git a/auth/pom.xml b/auth/pom.xml
index 753b896..52185e2 100644
--- a/auth/pom.xml
+++ b/auth/pom.xml
@@ -36,6 +36,11 @@
quarkus-oidc
provided
+
+ io.quarkus
+ quarkus-elytron-security-properties-file
+ provided
+
io.quarkus
quarkus-smallrye-fault-tolerance
diff --git a/auth/src/main/java/io/apicurio/common/apps/auth/authn/AppAuthenticationMechanism.java b/auth/src/main/java/io/apicurio/common/apps/auth/authn/AppAuthenticationMechanism.java
index 5c3e92b..b7cc32f 100644
--- a/auth/src/main/java/io/apicurio/common/apps/auth/authn/AppAuthenticationMechanism.java
+++ b/auth/src/main/java/io/apicurio/common/apps/auth/authn/AppAuthenticationMechanism.java
@@ -19,15 +19,13 @@
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
+import io.quarkus.arc.Unremovable;
+import io.quarkus.vertx.http.runtime.security.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.faulttolerance.Retry;
@@ -52,11 +50,6 @@
import io.quarkus.security.identity.IdentityProviderManager;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.AuthenticationRequest;
-import io.quarkus.security.identity.request.TokenAuthenticationRequest;
-import io.quarkus.vertx.http.runtime.security.ChallengeData;
-import io.quarkus.vertx.http.runtime.security.HttpAuthenticationMechanism;
-import io.quarkus.vertx.http.runtime.security.HttpCredentialTransport;
-import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser;
import io.smallrye.jwt.auth.principal.DefaultJWTParser;
import io.smallrye.jwt.auth.principal.ParseException;
import io.smallrye.mutiny.Uni;
@@ -71,16 +64,22 @@
@Alternative
@Priority(1)
@ApplicationScoped
+@Unremovable
public class AppAuthenticationMechanism implements HttpAuthenticationMechanism {
@ConfigProperty(name = "quarkus.oidc.tenant-enabled", defaultValue = "false")
@Info(category = "auth", description = "Enable auth", availableSince = "0.1.18-SNAPSHOT", registryAvailableSince = "2.0.0.Final", studioAvailableSince = "1.0.0")
- boolean authEnabled;
+ boolean oidcAuthEnabled;
+ // back to fake auth and use another property
@Dynamic(label = "HTTP basic authentication", description = "When selected, users are permitted to authenticate using HTTP basic authentication (in addition to OAuth).", requires = "apicurio.authn.enabled=true")
@ConfigProperty(name = "apicurio.authn.basic-client-credentials.enabled", defaultValue = "false")
@Info(category = "auth", description = "Enable basic auth client credentials", availableSince = "0.1.18-SNAPSHOT", registryAvailableSince = "2.1.0.Final", studioAvailableSince = "1.0.0")
- Supplier fakeBasicAuthEnabled;
+ Supplier basicClientCredentialsAuthEnabled;
+
+ @ConfigProperty(name = "quarkus.http.auth.basic", defaultValue = "false")
+ @Info(category = "auth", description = "Enable basic auth", availableSince = "1.1.X-SNAPSHOT", registryAvailableSince = "3.X.X.Final", studioAvailableSince = "1.0.0")
+ boolean basicAuthEnabled;
@ConfigProperty(name = "apicurio.authn.basic-client-credentials.cache-expiration", defaultValue = "10")
@Info(category = "auth", description = "Default client credentials token expiration time.", availableSince = "0.1.18-SNAPSHOT", registryAvailableSince = "2.2.6.Final", studioAvailableSince = "1.0.0")
@@ -111,6 +110,9 @@ public class AppAuthenticationMechanism implements HttpAuthenticationMechanism {
@Info(category = "auth", description = "Client identifier used by the server for authentication.", availableSince = "0.1.18-SNAPSHOT", registryAvailableSince = "2.0.0.Final", studioAvailableSince = "1.0.0")
String clientId;
+ @Inject
+ BasicAuthenticationMechanism basicAuthenticationMechanism;
+
@Inject
OidcAuthenticationMechanism oidcAuthenticationMechanism;
@@ -133,18 +135,30 @@ public class AppAuthenticationMechanism implements HttpAuthenticationMechanism {
@PostConstruct
public void init() {
- if (authEnabled) {
+ if (oidcAuthEnabled) {
cachedAccessTokens = new ConcurrentHashMap<>();
cachedAuthFailures = new ConcurrentHashMap<>();
httpClient = new VertxHttpClientProvider(vertx).create(authServerUrl, Collections.emptyMap(), null, new AuthErrorHandler());
}
}
+ private HttpAuthenticationMechanism selectEnabledAuth() {
+ if (basicAuthEnabled) {
+ return basicAuthenticationMechanism;
+ } else if (oidcAuthEnabled) {
+ return oidcAuthenticationMechanism;
+ } else {
+ return null;
+ }
+ }
+
@Override
public Uni authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
- if (authEnabled) {
+ if (basicAuthEnabled) {
+ return basicAuthenticationMechanism.authenticate(context, identityProviderManager);
+ } else if (oidcAuthEnabled) {
setAuditLogger(context);
- if (fakeBasicAuthEnabled.get()) {
+ if (basicClientCredentialsAuthEnabled.get()) {
final Pair clientCredentials = CredentialsHelper.extractCredentialsFromContext(context);
if (null != clientCredentials) {
try {
@@ -222,17 +236,30 @@ public String getForwardedFor() {
@Override
public Uni getChallenge(RoutingContext context) {
- return oidcAuthenticationMechanism.getChallenge(context);
+ var enabledAuth = selectEnabledAuth();
+ if (enabledAuth != null) {
+ return enabledAuth.getChallenge(context);
+ } else {
+ return Uni.createFrom().nullItem();
+ }
}
@Override
public Set> getCredentialTypes() {
- return Collections.singleton(TokenAuthenticationRequest.class);
+ Set> credentialTypes = new HashSet<>();
+ credentialTypes.addAll(oidcAuthenticationMechanism.getCredentialTypes());
+ credentialTypes.addAll(basicAuthenticationMechanism.getCredentialTypes());
+ return credentialTypes;
}
@Override
- public HttpCredentialTransport getCredentialTransport() {
- return new HttpCredentialTransport(HttpCredentialTransport.Type.AUTHORIZATION, "bearer");
+ public Uni getCredentialTransport(RoutingContext context) {
+ var enabledAuth = selectEnabledAuth();
+ if (enabledAuth != null) {
+ return enabledAuth.getCredentialTransport(context);
+ } else {
+ return Uni.createFrom().nullItem();
+ }
}
private Uni authenticateWithClientCredentials(Pair clientCredentials, RoutingContext context, IdentityProviderManager identityProviderManager) {