From 319b9f878a9e729330fed8ca64ca08f2ac029d80 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Thu, 22 Sep 2022 13:46:24 +0100 Subject: [PATCH] Update RestEasy Classic mappers and Vert.x HTTP to log messages related to 401 --- .../runtime/AuthenticationCompletionExceptionMapper.java | 5 +++++ .../runtime/AuthenticationFailedExceptionMapper.java | 8 ++++++++ .../resteasy/runtime/UnauthorizedExceptionMapper.java | 6 ++++++ .../vertx/http/runtime/security/HttpAuthenticator.java | 5 +++++ .../vertx/http/runtime/security/HttpSecurityRecorder.java | 1 + .../src/main/resources/application.properties | 7 ++++++- .../test/java/io/quarkus/it/keycloak/CodeFlowTest.java | 2 +- 7 files changed, 32 insertions(+), 2 deletions(-) diff --git a/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationCompletionExceptionMapper.java b/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationCompletionExceptionMapper.java index 62ff707749093..5d20cf5e312de 100644 --- a/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationCompletionExceptionMapper.java +++ b/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationCompletionExceptionMapper.java @@ -4,13 +4,18 @@ import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; +import org.jboss.logging.Logger; + import io.quarkus.security.AuthenticationCompletionException; @Provider public class AuthenticationCompletionExceptionMapper implements ExceptionMapper { + private static final Logger log = Logger.getLogger(AuthenticationCompletionExceptionMapper.class.getName()); + @Override public Response toResponse(AuthenticationCompletionException ex) { + log.debug("Authentication has failed, returning HTTP status 401"); return Response.status(401).build(); } diff --git a/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationFailedExceptionMapper.java b/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationFailedExceptionMapper.java index 778563f97aa07..c8f8c57a92ae0 100644 --- a/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationFailedExceptionMapper.java +++ b/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/AuthenticationFailedExceptionMapper.java @@ -7,6 +7,8 @@ import javax.ws.rs.ext.ExceptionMapper; import javax.ws.rs.ext.Provider; +import org.jboss.logging.Logger; + import io.quarkus.security.AuthenticationFailedException; import io.quarkus.vertx.http.runtime.CurrentVertxRequest; import io.quarkus.vertx.http.runtime.security.ChallengeData; @@ -16,6 +18,7 @@ @Provider @Priority(Priorities.USER + 1) public class AuthenticationFailedExceptionMapper implements ExceptionMapper { + private static final Logger log = Logger.getLogger(AuthenticationFailedExceptionMapper.class.getName()); private volatile CurrentVertxRequest currentVertxRequest; @@ -38,8 +41,13 @@ public Response toResponse(AuthenticationFailedException exception) { if (challengeData.headerName != null) { status.header(challengeData.headerName.toString(), challengeData.headerContent); } + log.debugf("Returning an authentication challenge, status code: %d", challengeData.status); return status.build(); + } else { + log.error("HttpAuthenticator is not found, returning HTTP status 401"); } + } else { + log.error("RoutingContext is not found, returning HTTP status 401"); } return Response.status(401).entity("Not Authenticated").build(); } diff --git a/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/UnauthorizedExceptionMapper.java b/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/UnauthorizedExceptionMapper.java index 0220d06890b22..478aa4ab70f8d 100644 --- a/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/UnauthorizedExceptionMapper.java +++ b/extensions/resteasy-classic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/UnauthorizedExceptionMapper.java @@ -48,11 +48,17 @@ public Response toResponse(UnauthorizedException exception) { if (challengeData.headerName != null) { status.header(challengeData.headerName.toString(), challengeData.headerContent); } + log.debugf("Returning an authentication challenge, status code: %d", challengeData.status); return status.build(); } else { + log.debug("ChallengeData is null, returning HTTP status 401"); return Response.status(401).build(); } + } else { + log.error("HttpAuthenticator is not found, returning HTTP status 401"); } + } else { + log.error("RoutingContext is not found, returning HTTP status 401"); } return Response.status(401).entity("Not authorized").build(); } diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpAuthenticator.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpAuthenticator.java index 8b2de1d915bd1..f8738d9c63902 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpAuthenticator.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpAuthenticator.java @@ -11,6 +11,8 @@ import javax.enterprise.inject.Instance; import javax.inject.Singleton; +import org.jboss.logging.Logger; + import io.netty.handler.codec.http.HttpResponseStatus; import io.quarkus.security.identity.IdentityProvider; import io.quarkus.security.identity.IdentityProviderManager; @@ -25,6 +27,8 @@ */ @Singleton public class HttpAuthenticator { + private static final Logger log = Logger.getLogger(HttpAuthenticator.class); + private final IdentityProviderManager identityProviderManager; private final Instance pathMatchingPolicy; private final HttpAuthenticationMechanism[] mechanisms; @@ -164,6 +168,7 @@ public Uni apply(Boolean authDone) { @Override public Uni apply(Boolean authDone) { if (!authDone) { + log.debug("Authentication has not been done, returning HTTP status 401"); routingContext.response().setStatusCode(401); routingContext.response().end(); } diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java index bfa66e192044b..f4ca987fb85a2 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/security/HttpSecurityRecorder.java @@ -92,6 +92,7 @@ public void accept(Throwable throwable) { } }); } else if (throwable instanceof AuthenticationCompletionException) { + log.debug("Authentication has failed, returning HTTP status 401"); event.response().setStatusCode(401); event.response().end(); } else if (throwable instanceof AuthenticationRedirectException) { diff --git a/integration-tests/oidc-code-flow/src/main/resources/application.properties b/integration-tests/oidc-code-flow/src/main/resources/application.properties index 5b00192e9c8b6..86ef300680fac 100644 --- a/integration-tests/oidc-code-flow/src/main/resources/application.properties +++ b/integration-tests/oidc-code-flow/src/main/resources/application.properties @@ -85,7 +85,7 @@ quarkus.oidc.tenant-refresh.authentication.cookie-path=/tenant-refresh quarkus.oidc.tenant-refresh.authentication.session-age-extension=2M quarkus.oidc.tenant-refresh.token.refresh-expired=true -quarkus.oidc.tenant-autorefresh.auth-server-url=${keycloak.url}/realms/logout-realm +quarkus.oidc.tenant-autorefresh.auth-server-url=${keycloak.url}/realms/quarkus quarkus.oidc.tenant-autorefresh.client-id=quarkus-app quarkus.oidc.tenant-autorefresh.credentials.secret=secret quarkus.oidc.tenant-autorefresh.application-type=web-app @@ -171,5 +171,10 @@ quarkus.http.proxy.allow-forwarded=true quarkus.log.category."io.quarkus.oidc.runtime.CodeAuthenticationMechanism".min-level=TRACE quarkus.log.category."io.quarkus.oidc.runtime.CodeAuthenticationMechanism".level=TRACE +quarkus.log.category."io.quarkus.resteasy.runtime.AuthenticationFailedExceptionMapper".level=DEBUG +quarkus.log.category."io.quarkus.resteasy.runtime.AuthenticationCompletionExceptionMapper".level=DEBUG +quarkus.log.category."io.quarkus.resteasy.runtime.UnauthorizedExceptionMapper".level=DEBUG +quarkus.log.category."io.quarkus.vertx.http.runtime.security.HttpAuthenticator".level=DEBUG +quarkus.log.category."io.quarkus.vertx.http.runtime.security.HttpSecurityRecorder".level=DEBUG quarkus.log.category."com.gargoylesoftware.htmlunit.javascript.host.css.CSSStyleSheet".level=FATAL diff --git a/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java b/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java index ede67aad0d2bb..1da09eeae744d 100644 --- a/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java +++ b/integration-tests/oidc-code-flow/src/test/java/io/quarkus/it/keycloak/CodeFlowTest.java @@ -502,7 +502,7 @@ public Boolean call() throws Exception { public void testTokenAutoRefresh() throws IOException { try (final WebClient webClient = createWebClient()) { HtmlPage page = webClient.getPage("http://localhost:8081/tenant-autorefresh"); - assertEquals("Sign in to logout-realm", page.getTitleText()); + assertEquals("Sign in to quarkus", page.getTitleText()); HtmlForm loginForm = page.getForms().get(0); loginForm.getInputByName("username").setValueAttribute("alice"); loginForm.getInputByName("password").setValueAttribute("alice");