KEYCLOAK-8310 Change scheme option to alwaysHttps option
This commit is contained in:
parent
393ff50b8d
commit
5f0424fb11
4 changed files with 96 additions and 57 deletions
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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}"
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue