From 90ae1ac8ad0a67227dd589f4d8c6053bbb3e8b6b Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 23 Mar 2021 18:03:47 +0000 Subject: [PATCH] KeycloakPolicyEnforcerAuthorizer should permit if authentication is not done by OIDC --- .../KeycloakPolicyEnforcerAuthorizer.java | 14 ++++++++++- .../keycloak/pep/runtime/VertxHttpFacade.java | 24 ++++--------------- .../it/keycloak/ProtectedResource2.java | 17 +++++++++++++ 3 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/ProtectedResource2.java diff --git a/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/KeycloakPolicyEnforcerAuthorizer.java b/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/KeycloakPolicyEnforcerAuthorizer.java index 5c9bafafe9073..01ef1a3bf166c 100644 --- a/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/KeycloakPolicyEnforcerAuthorizer.java +++ b/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/KeycloakPolicyEnforcerAuthorizer.java @@ -18,11 +18,13 @@ import org.keycloak.representations.adapters.config.AdapterConfig; import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; +import io.quarkus.oidc.AccessTokenCredential; import io.quarkus.oidc.OidcTenantConfig; import io.quarkus.oidc.common.runtime.OidcCommonConfig.Tls.Verification; import io.quarkus.oidc.runtime.OidcConfig; import io.quarkus.runtime.TlsConfig; import io.quarkus.security.AuthenticationFailedException; +import io.quarkus.security.credential.TokenCredential; import io.quarkus.security.identity.SecurityIdentity; import io.quarkus.security.runtime.QuarkusSecurityIdentity; import io.quarkus.vertx.http.runtime.HttpConfiguration; @@ -51,7 +53,17 @@ public CheckResult apply(RoutingContext routingContext, SecurityIdentity identit "Keycloak Policy Enforcer has not been initialized - please make sure 'quarkus.oidc.enabled' is not set to 'false'"); throw new AuthenticationFailedException(); } - VertxHttpFacade httpFacade = new VertxHttpFacade(routingContext, readTimeout); + + TokenCredential credential = identity.getCredential(AccessTokenCredential.class); + + if (credential == null) { + // If SecurityIdentity has been created by the authentication mechanism other than quarkus-oidc then do not block + // the request. + return CheckResult.PERMIT; + } + + String token = credential.getToken(); + VertxHttpFacade httpFacade = new VertxHttpFacade(routingContext, token, readTimeout); AuthorizationContext result = delegate.authorize(httpFacade); if (result.isGranted()) { diff --git a/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/VertxHttpFacade.java b/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/VertxHttpFacade.java index 19eeb9922df5c..ea02e3e5b65a4 100644 --- a/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/VertxHttpFacade.java +++ b/extensions/keycloak-authorization/runtime/src/main/java/io/quarkus/keycloak/pep/runtime/VertxHttpFacade.java @@ -19,11 +19,7 @@ import org.keycloak.representations.AccessToken; import io.netty.handler.codec.http.HttpHeaderNames; -import io.quarkus.oidc.AccessTokenCredential; -import io.quarkus.security.credential.TokenCredential; -import io.quarkus.security.identity.SecurityIdentity; import io.quarkus.vertx.http.runtime.VertxInputStream; -import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser; import io.vertx.core.buffer.Buffer; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.HttpServerResponse; @@ -35,13 +31,15 @@ public class VertxHttpFacade implements OIDCHttpFacade { private final Response response; private final RoutingContext routingContext; private final Request request; + private final String token; private final long readTimeout; - public VertxHttpFacade(RoutingContext routingContext, long readTimeout) { + public VertxHttpFacade(RoutingContext routingContext, String token, long readTimeout) { this.routingContext = routingContext; + this.token = token; this.readTimeout = readTimeout; - request = createRequest(routingContext); - response = createResponse(routingContext); + this.request = createRequest(routingContext); + this.response = createResponse(routingContext); } @Override @@ -222,18 +220,6 @@ public void end() { @Override public KeycloakSecurityContext getSecurityContext() { - SecurityIdentity identity = QuarkusHttpUser.getSecurityIdentityBlocking(routingContext, null); - if (identity == null) { - return null; - } - TokenCredential credential = identity.getCredential(AccessTokenCredential.class); - - if (credential == null) { - return null; - } - - String token = credential.getToken(); - try { return new KeycloakSecurityContext(token, new JWSInput(token).readJsonContent(AccessToken.class), null, null); } catch (JWSInputException e) { diff --git a/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/ProtectedResource2.java b/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/ProtectedResource2.java new file mode 100644 index 0000000000000..ea5e91e9d4a26 --- /dev/null +++ b/integration-tests/keycloak-authorization/src/main/java/io/quarkus/it/keycloak/ProtectedResource2.java @@ -0,0 +1,17 @@ +package io.quarkus.it.keycloak; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import io.quarkus.security.Authenticated; + +@Path("/api2/resource") +@Authenticated +public class ProtectedResource2 { + + @GET + public String testResource() { + // This method must not be invoked + throw new RuntimeException(); + } +}