keycloak-memoizeit

Details

diff --git a/services/src/main/java/org/keycloak/url/FixedHostnameProvider.java b/services/src/main/java/org/keycloak/url/FixedHostnameProvider.java
index 0e31578..e438e87 100644
--- a/services/src/main/java/org/keycloak/url/FixedHostnameProvider.java
+++ b/services/src/main/java/org/keycloak/url/FixedHostnameProvider.java
@@ -10,13 +10,13 @@ public class FixedHostnameProvider implements HostnameProvider {
 
     private final KeycloakSession session;
     private final String globalHostname;
-    private final String scheme;
+    private final boolean alwaysHttps;
     private final int httpPort;
     private final int httpsPort;
 
-    public FixedHostnameProvider(KeycloakSession session, String scheme, String globalHostname, int httpPort, int httpsPort) {
+    public FixedHostnameProvider(KeycloakSession session, boolean alwaysHttps, String globalHostname, int httpPort, int httpsPort) {
         this.session = session;
-        this.scheme = scheme;
+        this.alwaysHttps = alwaysHttps;
         this.globalHostname = globalHostname;
         this.httpPort = httpPort;
         this.httpsPort = httpsPort;
@@ -24,7 +24,7 @@ public class FixedHostnameProvider implements HostnameProvider {
 
     @Override
     public String getScheme(UriInfo originalUriInfo) {
-        return scheme != null ? scheme : originalUriInfo.getRequestUri().getScheme();
+        return alwaysHttps ? "https" : originalUriInfo.getRequestUri().getScheme();
     }
 
     @Override
@@ -50,6 +50,12 @@ public class FixedHostnameProvider implements HostnameProvider {
             } else {
                 return httpsPort;
             }
+        } else if (alwaysHttps) {
+            if (httpsPort == 443) {
+                return -1;
+            } else {
+                return httpsPort;
+            }
         } else {
             if (httpPort == -1) {
                 return originalUriInfo.getRequestUri().getPort();
diff --git a/services/src/main/java/org/keycloak/url/FixedHostnameProviderFactory.java b/services/src/main/java/org/keycloak/url/FixedHostnameProviderFactory.java
index 25a030e..e7e96d9 100644
--- a/services/src/main/java/org/keycloak/url/FixedHostnameProviderFactory.java
+++ b/services/src/main/java/org/keycloak/url/FixedHostnameProviderFactory.java
@@ -10,11 +10,11 @@ public class FixedHostnameProviderFactory implements HostnameProviderFactory {
     private String hostname;
     private int httpPort;
     private int httpsPort;
-    private String scheme;
+    private boolean alwaysHttps;
 
     @Override
     public HostnameProvider create(KeycloakSession session) {
-        return new FixedHostnameProvider(session, scheme, hostname, httpPort, httpsPort);
+        return new FixedHostnameProvider(session, alwaysHttps, hostname, httpPort, httpsPort);
     }
 
     @Override
@@ -26,10 +26,7 @@ public class FixedHostnameProviderFactory implements HostnameProviderFactory {
 
         this.httpPort = config.getInt("httpPort", -1);
         this.httpsPort = config.getInt("httpsPort", -1);
-        this.scheme = config.get("scheme");
-        if (scheme != null && scheme.trim().isEmpty()) {
-            scheme = null;
-        }
+        this.alwaysHttps = config.getBoolean("alwaysHttps", false);
     }
 
     @Override
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java
index 35381af..1ece435 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/url/FixedHostnameTest.java
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.jboss.arquillian.container.test.api.ContainerController;
 import org.jboss.arquillian.test.api.ArquillianResource;
+import org.junit.Before;
 import org.junit.Test;
 import org.keycloak.client.registration.Auth;
 import org.keycloak.client.registration.ClientRegistration;
@@ -19,12 +20,11 @@ import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.testsuite.AbstractKeycloakTest;
 import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
-import org.keycloak.testsuite.util.ClientBuilder;
 import org.keycloak.testsuite.util.OAuthClient;
 import org.wildfly.extras.creaper.core.online.OnlineManagementClient;
 import org.wildfly.extras.creaper.core.online.operations.admin.Administration;
 
-import java.io.IOException;
+import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.List;
 
@@ -37,6 +37,16 @@ public class FixedHostnameTest extends AbstractKeycloakTest {
     @ArquillianResource
     protected ContainerController controller;
 
+    String authServerUrl;
+
+    String suiteScheme;
+
+    @Before
+    public void before() throws URISyntaxException {
+        suiteScheme = suiteContext.getAuthServerInfo().getContextRoot().toURI().getScheme();
+        authServerUrl = suiteContext.getAuthServerInfo().getContextRoot() + "/auth";
+    }
+
     @Override
     public void addTestRealms(List<RealmRepresentation> testRealms) {
         RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class);
@@ -56,55 +66,83 @@ public class FixedHostnameTest extends AbstractKeycloakTest {
         oauth.clientId("direct-grant");
 
         try {
-            assertWellKnown("test", "http","localhost");
+            assertWellKnown("test", suiteScheme + "://localhost:8180");
 
-            configureFixedHostname(null);
+            configureFixedHostname(-1, -1, false);
 
-            assertWellKnown("test", "http","keycloak.127.0.0.1.nip.io");
-            assertWellKnown("hostname", "http","custom-domain.127.0.0.1.nip.io");
+            assertWellKnown("test", suiteScheme + "://keycloak.127.0.0.1.nip.io:8180");
+            assertWellKnown("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io:8180");
 
-            assertTokenIssuer("test", "http","keycloak.127.0.0.1.nip.io");
-            assertTokenIssuer("hostname", "http","custom-domain.127.0.0.1.nip.io");
+            assertTokenIssuer("test", suiteScheme + "://keycloak.127.0.0.1.nip.io:8180");
+            assertTokenIssuer("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io:8180");
 
-            assertInitialAccessTokenFromMasterRealm("test","http","keycloak.127.0.0.1.nip.io");
-            assertInitialAccessTokenFromMasterRealm("hostname", "http","custom-domain.127.0.0.1.nip.io");
+            assertInitialAccessTokenFromMasterRealm("test", suiteScheme + "://keycloak.127.0.0.1.nip.io:8180");
+            assertInitialAccessTokenFromMasterRealm("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io:8180");
         } finally {
             clearFixedHostname();
         }
     }
 
     @Test
-    public void fixedHostnameAndScheme() throws Exception {
+    public void fixedHttpPort() throws Exception {
+        // Make sure request are always sent with http
+        authServerUrl = authServerUrl.replace("https://", "http://");
+
         oauth.clientId("direct-grant");
 
         try {
-            assertWellKnown("test", "http","localhost");
+            assertWellKnown("test", suiteScheme + "://localhost:8180");
 
-            configureFixedHostname("https");
+            configureFixedHostname(80, -1, false);
 
-            assertWellKnown("test", "https","keycloak.127.0.0.1.nip.io");
-            assertWellKnown("hostname", "https","custom-domain.127.0.0.1.nip.io");
+            assertWellKnown("test", suiteScheme + "://keycloak.127.0.0.1.nip.io");
+            assertWellKnown("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io");
 
-            assertTokenIssuer("test", "https","keycloak.127.0.0.1.nip.io");
-            assertTokenIssuer("hostname", "https","custom-domain.127.0.0.1.nip.io");
+            assertTokenIssuer("test", suiteScheme + "://keycloak.127.0.0.1.nip.io");
+            assertTokenIssuer("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io");
 
-            assertInitialAccessTokenFromMasterRealm("test", "https", "keycloak.127.0.0.1.nip.io");
-            assertInitialAccessTokenFromMasterRealm("hostname", "https", "custom-domain.127.0.0.1.nip.io");
+            assertInitialAccessTokenFromMasterRealm("test", suiteScheme + "://keycloak.127.0.0.1.nip.io");
+            assertInitialAccessTokenFromMasterRealm("hostname", suiteScheme + "://custom-domain.127.0.0.1.nip.io");
         } finally {
             clearFixedHostname();
         }
     }
 
-    private void assertInitialAccessTokenFromMasterRealm(String realm, String expectedScheme, String expectedHostname) throws JWSInputException, ClientRegistrationException {
+    @Test
+    public void fixedHostnameAlwaysHttpsHttpsPort() throws Exception {
+        // Make sure request are always sent with http
+        authServerUrl = authServerUrl.replace("https://", "http://");
+
+        oauth.clientId("direct-grant");
+
+        try {
+            assertWellKnown("test", suiteScheme + "://localhost:8180");
+
+            configureFixedHostname(-1, 443, true);
+
+            assertWellKnown("test", "https://keycloak.127.0.0.1.nip.io");
+            assertWellKnown("hostname", "https://custom-domain.127.0.0.1.nip.io");
+
+            assertTokenIssuer("test", "https://keycloak.127.0.0.1.nip.io");
+            assertTokenIssuer("hostname", "https://custom-domain.127.0.0.1.nip.io");
+
+            assertInitialAccessTokenFromMasterRealm("test", "https://keycloak.127.0.0.1.nip.io");
+            assertInitialAccessTokenFromMasterRealm("hostname", "https://custom-domain.127.0.0.1.nip.io");
+        } finally {
+            clearFixedHostname();
+        }
+    }
+
+    private void assertInitialAccessTokenFromMasterRealm(String realm, String expectedBaseUrl) throws JWSInputException, ClientRegistrationException {
         ClientInitialAccessCreatePresentation rep = new ClientInitialAccessCreatePresentation();
         rep.setCount(1);
         rep.setExpiration(10000);
 
         ClientInitialAccessPresentation initialAccess = adminClient.realm(realm).clientInitialAccess().create(rep);
         JsonWebToken token = new JWSInput(initialAccess.getToken()).readJsonContent(JsonWebToken.class);
-        assertEquals(expectedScheme + "://" + expectedHostname + ":8180/auth/realms/" + realm, token.getIssuer());
+        assertEquals(expectedBaseUrl + "/auth/realms/" + realm, token.getIssuer());
 
-        ClientRegistration clientReg = ClientRegistration.create().url(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", realm).build();
+        ClientRegistration clientReg = ClientRegistration.create().url(authServerUrl, realm).build();
         clientReg.auth(Auth.token(initialAccess.getToken()));
 
         ClientRepresentation client = new ClientRepresentation();
@@ -113,34 +151,36 @@ public class FixedHostnameTest extends AbstractKeycloakTest {
 
         String registrationAccessToken = response.getRegistrationAccessToken();
         JsonWebToken registrationToken = new JWSInput(registrationAccessToken).readJsonContent(JsonWebToken.class);
-        assertEquals(expectedScheme + "://" + expectedHostname + ":8180/auth/realms/" + realm, registrationToken.getIssuer());
+        assertEquals(expectedBaseUrl + "/auth/realms/" + realm, registrationToken.getIssuer());
     }
 
-    private void assertTokenIssuer(String realm, String expectedScheme, String expectedHostname) throws Exception {
+    private void assertTokenIssuer(String realm, String expectedBaseUrl) throws Exception {
+        oauth.baseUrl(authServerUrl);
         oauth.realm(realm);
 
         OAuthClient.AccessTokenResponse tokenResponse = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
 
         AccessToken token = new JWSInput(tokenResponse.getAccessToken()).readJsonContent(AccessToken.class);
-        assertEquals(expectedScheme + "://" + expectedHostname + ":8180/auth/realms/" + realm, token.getIssuer());
+        assertEquals(expectedBaseUrl + "/auth/realms/" + realm, token.getIssuer());
 
         String introspection = oauth.introspectAccessTokenWithClientCredential(oauth.getClientId(), "password", tokenResponse.getAccessToken());
         ObjectMapper objectMapper = new ObjectMapper();
         JsonNode introspectionNode = objectMapper.readTree(introspection);
         assertTrue(introspectionNode.get("active").asBoolean());
-        assertEquals(expectedScheme + "://" + expectedHostname + ":8180/auth/realms/" + realm, introspectionNode.get("iss").asText());
+        assertEquals(expectedBaseUrl + "/auth/realms/" + realm, introspectionNode.get("iss").asText());
     }
 
-    private void assertWellKnown(String realm, String expectedScheme, String expectedHostname) {
+    private void assertWellKnown(String realm, String expectedBaseUrl) {
+        oauth.baseUrl(authServerUrl);
         OIDCConfigurationRepresentation config = oauth.doWellKnownRequest(realm);
-        assertEquals(expectedScheme + "://" + expectedHostname + ":8180/auth/realms/" + realm + "/protocol/openid-connect/token", config.getTokenEndpoint());
+        assertEquals(expectedBaseUrl + "/auth/realms/" + realm + "/protocol/openid-connect/token", config.getTokenEndpoint());
     }
 
-    private void configureFixedHostname(String scheme) throws Exception {
+    private void configureFixedHostname(int httpPort, int httpsPort, boolean alwaysHttps) throws Exception {
         if (suiteContext.getAuthServerInfo().isUndertow()) {
-            configureUndertow("fixed", "keycloak.127.0.0.1.nip.io", scheme);
+            configureUndertow("fixed", "keycloak.127.0.0.1.nip.io", httpPort, httpsPort, alwaysHttps);
         } else if (suiteContext.getAuthServerInfo().isJBossBased()) {
-            configureWildFly("fixed", "keycloak.127.0.0.1.nip.io", scheme);
+            configureWildFly("fixed", "keycloak.127.0.0.1.nip.io", httpPort, httpsPort, alwaysHttps);
         } else {
             throw new RuntimeException("Don't know how to config");
         }
@@ -151,9 +191,9 @@ public class FixedHostnameTest extends AbstractKeycloakTest {
 
     private void clearFixedHostname() throws Exception {
         if (suiteContext.getAuthServerInfo().isUndertow()) {
-            configureUndertow("request", "localhost", null);
+            configureUndertow("request", "localhost", -1, -1,false);
         } else if (suiteContext.getAuthServerInfo().isJBossBased()) {
-            configureWildFly("request", "localhost", null);
+            configureWildFly("request", "localhost", -1, -1, false);
         } else {
             throw new RuntimeException("Don't know how to config");
         }
@@ -161,31 +201,27 @@ public class FixedHostnameTest extends AbstractKeycloakTest {
         reconnectAdminClient();
     }
 
-    private void configureUndertow(String provider, String hostname, String scheme) {
+    private void configureUndertow(String provider, String hostname, int httpPort, int httpsPort, boolean alwaysHttps) {
         controller.stop(suiteContext.getAuthServerInfo().getQualifier());
 
         System.setProperty("keycloak.hostname.provider", provider);
         System.setProperty("keycloak.hostname.fixed.hostname", hostname);
-        if (scheme != null) {
-            System.setProperty("keycloak.hostname.fixed.scheme", scheme);
-        } else {
-            System.getProperties().remove("keycloak.hostname.fixed.scheme");
-        }
+        System.setProperty("keycloak.hostname.fixed.httpPort", String.valueOf(httpPort));
+        System.setProperty("keycloak.hostname.fixed.httpsPort", String.valueOf(httpsPort));
+        System.setProperty("keycloak.hostname.fixed.alwaysHttps", String.valueOf(alwaysHttps));
 
         controller.start(suiteContext.getAuthServerInfo().getQualifier());
     }
 
-    private void configureWildFly(String provider, String hostname, String scheme) throws Exception {
+    private void configureWildFly(String provider, String hostname, int httpPort, int httpsPort, boolean alwaysHttps) throws Exception {
         OnlineManagementClient client = AuthServerTestEnricher.getManagementClient();
         Administration administration = new Administration(client);
 
         client.execute("/subsystem=keycloak-server/spi=hostname:write-attribute(name=default-provider, value=" + provider + ")");
         client.execute("/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.hostname,value=" + hostname + ")");
-        if (scheme != null) {
-            client.execute("/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.scheme,value=" + scheme + ")");
-        } else {
-            client.execute("/subsystem=keycloak-server/spi=hostname/provider=fixed:map-remove(name=properties,key=scheme)");
-        }
+        client.execute("/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.httpPort,value=" + httpPort + ")");
+        client.execute("/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.httpsPort,value=" + httpsPort + ")");
+        client.execute("/subsystem=keycloak-server/spi=hostname/provider=fixed:write-attribute(name=properties.alwaysHttps,value=" + alwaysHttps + ")");
 
         administration.reloadIfRequired();
 
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
index 3fd578e..79ced07 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json
@@ -6,8 +6,8 @@
         "fixed": {
             "hostname": "${keycloak.hostname.fixed.hostname:localhost}",
             "httpPort": "${keycloak.hostname.fixed.httpPort:-1}",
-            "httpsPort": "${keycloak.hostname.fixed.httpPorts:-1}",
-            "scheme": "${keycloak.hostname.fixed.scheme:}"
+            "httpsPort": "${keycloak.hostname.fixed.httpsPort:-1}",
+            "alwaysHttps": "${keycloak.hostname.fixed.alwaysHttps:false}"
         }
     },