diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/hostname/DefaultHostnameProvider.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/hostname/DefaultHostnameProvider.java index d081643c6e..f28a4c68a8 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/hostname/DefaultHostnameProvider.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/hostname/DefaultHostnameProvider.java @@ -17,6 +17,7 @@ package org.keycloak.quarkus.runtime.hostname; +import static org.keycloak.common.util.UriUtils.checkUrl; import static org.keycloak.urls.UrlType.ADMIN; import static org.keycloak.urls.UrlType.BACKEND; import static org.keycloak.urls.UrlType.FRONTEND; @@ -31,6 +32,7 @@ import java.util.function.Function; import javax.ws.rs.core.UriInfo; import org.jboss.logging.Logger; import org.keycloak.Config; +import org.keycloak.common.enums.SslRequired; import org.keycloak.common.util.Resteasy; import org.keycloak.config.HostnameOptions; import org.keycloak.models.KeycloakSession; @@ -185,9 +187,14 @@ public final class DefaultHostnameProvider implements HostnameProvider, Hostname String frontendUrl = realm.getAttribute("frontendUrl"); if (isNotBlank(frontendUrl)) { - realmUrl = URI.create(frontendUrl); - session.setAttribute(realmUriKey, realmUrl); - return realmUrl; + try { + checkUrl(SslRequired.NONE, frontendUrl, "frontendUrl"); + realmUrl = URI.create(frontendUrl); + session.setAttribute(realmUriKey, realmUrl); + return realmUrl; + } catch (IllegalArgumentException e) { + LOGGER.errorf(e, "Failed to parse realm frontendUrl '%s'. Falling back to global value.", frontendUrl); + } } } diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java index 8cbf09d0dd..572fdb6e65 100755 --- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java @@ -272,7 +272,7 @@ public class RealmsResource { } private void checkSsl(RealmModel realm) { - if (!session.getContext().getUri().getBaseUri().getScheme().equals("https") + if (!"https".equals(session.getContext().getUri().getBaseUri().getScheme()) && realm.getSslRequired().isRequired(session.getContext().getConnection())) { HttpRequest request = session.getContext().getHttpRequest(); Cors cors = Cors.add(request).auth().allowedMethods(request.getHttpMethod()).auth().exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS); diff --git a/services/src/main/java/org/keycloak/url/DefaultHostnameProvider.java b/services/src/main/java/org/keycloak/url/DefaultHostnameProvider.java index 9f01d84957..c7f3c415ac 100644 --- a/services/src/main/java/org/keycloak/url/DefaultHostnameProvider.java +++ b/services/src/main/java/org/keycloak/url/DefaultHostnameProvider.java @@ -1,6 +1,10 @@ package org.keycloak.url; +import static org.keycloak.common.util.UriUtils.checkUrl; +import static org.keycloak.utils.StringUtil.isNotBlank; + import org.jboss.logging.Logger; +import org.keycloak.common.enums.SslRequired; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.urls.HostnameProvider; @@ -8,7 +12,6 @@ import org.keycloak.urls.UrlType; import javax.ws.rs.core.UriInfo; import java.net.URI; -import java.net.URISyntaxException; public class DefaultHostnameProvider implements HostnameProvider { @@ -97,11 +100,12 @@ public class DefaultHostnameProvider implements HostnameProvider { realmUri = null; String realmFrontendUrl = session.getContext().getRealm().getAttribute("frontendUrl"); - if (realmFrontendUrl != null && !realmFrontendUrl.isEmpty()) { + if (isNotBlank(realmFrontendUrl)) { try { - realmUri = new URI(realmFrontendUrl); - } catch (URISyntaxException e) { - LOGGER.error("Failed to parse realm frontendUrl. Falling back to global value.", e); + checkUrl(SslRequired.NONE, realmFrontendUrl, "frontendUrl"); + realmUri = URI.create(realmFrontendUrl); + } catch (IllegalArgumentException e) { + LOGGER.errorf(e, "Failed to parse realm frontendUrl '%s'. Falling back to global value.", realmFrontendUrl); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/DefaultHostnameTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/DefaultHostnameTest.java index 2ad2ef5f5e..75ad4de29a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/DefaultHostnameTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/DefaultHostnameTest.java @@ -13,7 +13,6 @@ import org.keycloak.broker.provider.util.SimpleHttp; import org.keycloak.client.registration.Auth; import org.keycloak.client.registration.ClientRegistration; import org.keycloak.client.registration.ClientRegistrationException; -import org.keycloak.common.Profile; import org.keycloak.common.util.UriUtils; import org.keycloak.jose.jws.JWSInput; import org.keycloak.jose.jws.JWSInputException; @@ -26,8 +25,6 @@ import org.keycloak.representations.idm.ClientInitialAccessPresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude; -import org.keycloak.testsuite.arquillian.annotation.DisableFeature; -import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.util.AdminClientUtil; import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.OAuthClient; @@ -126,6 +123,26 @@ public class DefaultHostnameTest extends AbstractHostnameTest { } } + @Test + public void wrongProtocolRealmFrontendUrl() throws Exception { + expectedBackendUrl = transformUrlIfQuarkusServer(AUTH_SERVER_ROOT); + oauth.clientId("direct-grant"); + + RealmResource realmResource = realmsResouce().realm("frontendUrl"); + RealmRepresentation rep = realmResource.toRepresentation(); + + try { + rep.getAttributes().put("frontendUrl", "wrong://example.com"); + realmResource.update(rep); + + assertWellKnown("frontendUrl", transformUrlIfQuarkusServer(AUTH_SERVER_ROOT)); + } finally { + rep.getAttributes().put("frontendUrl", realmFrontEndUrl); + realmResource.update(rep); + reset(); + } + } + @Test public void fixedAdminUrl() throws Exception { expectedBackendUrl = transformUrlIfQuarkusServer(AUTH_SERVER_ROOT);