diff --git a/services/src/main/java/org/keycloak/services/resources/Cors.java b/services/src/main/java/org/keycloak/services/resources/Cors.java index f938a5f487..c9bfa030fe 100755 --- a/services/src/main/java/org/keycloak/services/resources/Cors.java +++ b/services/src/main/java/org/keycloak/services/resources/Cors.java @@ -133,7 +133,11 @@ public class Cors { return builder.build(); } - builder.header(ACCESS_CONTROL_ALLOW_ORIGIN, origin); + if (allowedOrigins != null && allowedOrigins.contains(ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD)) { + builder.header(ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD); + } else { + builder.header(ACCESS_CONTROL_ALLOW_ORIGIN, origin); + } if (preflight) { if (allowedMethods != null) { @@ -178,7 +182,11 @@ public class Cors { logger.debug("build CORS headers and return"); - response.getOutputHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, origin); + if (allowedOrigins.contains(ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD)) { + response.getOutputHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_ALLOW_ORIGIN_WILDCARD); + } else { + response.getOutputHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN, origin); + } if (preflight) { if (allowedMethods != null) { 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 bb8de2d918..bc3f8dc19a 100755 --- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java @@ -260,8 +260,7 @@ public class RealmsResource { WellKnownProvider wellKnown = session.getProvider(WellKnownProvider.class, providerName); if (wellKnown != null) { - ResponseBuilder responseBuilder = Response.ok(wellKnown.getConfig()) - .cacheControl(CacheControlUtil.getDefaultCacheControl()); + ResponseBuilder responseBuilder = Response.ok(wellKnown.getConfig()).cacheControl(CacheControlUtil.noCache()); return Cors.add(request, responseBuilder).allowedOrigins("*").auth().build(); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCWellKnownProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCWellKnownProviderTest.java index 0203eb13f2..c4a6c459cf 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCWellKnownProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCWellKnownProviderTest.java @@ -29,6 +29,7 @@ import org.keycloak.representations.IDToken; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.clientregistration.ClientRegistrationService; import org.keycloak.services.clientregistration.oidc.OIDCClientRegistrationProviderFactory; +import org.keycloak.services.resources.Cors; import org.keycloak.services.resources.RealmsResource; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.Assert; @@ -38,12 +39,16 @@ import org.keycloak.testsuite.util.OAuthClient; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import java.net.URI; import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * @author Marek Posolda */ @@ -75,10 +80,10 @@ public class OIDCWellKnownProviderTest extends AbstractKeycloakTest { OIDCConfigurationRepresentation oidcConfig = getOIDCDiscoveryConfiguration(client); // URIs are filled - Assert.assertEquals(oidcConfig.getAuthorizationEndpoint(), OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)).build("test").toString()); - Assert.assertEquals(oidcConfig.getTokenEndpoint(), oauth.getAccessTokenUrl()); - Assert.assertEquals(oidcConfig.getUserinfoEndpoint(), OIDCLoginProtocolService.userInfoUrl(UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)).build("test").toString()); - Assert.assertEquals(oidcConfig.getJwksUri(), oauth.getCertsUrl("test")); + assertEquals(oidcConfig.getAuthorizationEndpoint(), OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)).build("test").toString()); + assertEquals(oidcConfig.getTokenEndpoint(), oauth.getAccessTokenUrl()); + assertEquals(oidcConfig.getUserinfoEndpoint(), OIDCLoginProtocolService.userInfoUrl(UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT)).build("test").toString()); + assertEquals(oidcConfig.getJwksUri(), oauth.getCertsUrl("test")); String registrationUri = UriBuilder .fromUri(OAuthClient.AUTH_SERVER_ROOT) @@ -87,7 +92,7 @@ public class OIDCWellKnownProviderTest extends AbstractKeycloakTest { .path(ClientRegistrationService.class, "provider") .build("test", OIDCClientRegistrationProviderFactory.ID) .toString(); - Assert.assertEquals(oidcConfig.getRegistrationEndpoint(), registrationUri); + assertEquals(oidcConfig.getRegistrationEndpoint(), registrationUri); // Support standard + implicit + hybrid flow assertContains(oidcConfig.getResponseTypesSupported(), OAuth2Constants.CODE, OIDCResponseType.ID_TOKEN, "id_token token", "code id_token", "code token", "code id_token token"); @@ -123,7 +128,7 @@ public class OIDCWellKnownProviderTest extends AbstractKeycloakTest { public void testIssuerMatches() throws Exception { OAuthClient.AuthorizationEndpointResponse authzResp = oauth.doLogin("test-user@localhost", "password"); OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(authzResp.getCode(), "password"); - Assert.assertEquals(200, response.getStatusCode()); + assertEquals(200, response.getStatusCode()); IDToken idToken = oauth.verifyIDToken(response.getIdToken()); Client client = ClientBuilder.newClient(); @@ -131,18 +136,36 @@ public class OIDCWellKnownProviderTest extends AbstractKeycloakTest { OIDCConfigurationRepresentation oidcConfig = getOIDCDiscoveryConfiguration(client); // assert issuer matches - Assert.assertEquals(idToken.getIssuer(), oidcConfig.getIssuer()); + assertEquals(idToken.getIssuer(), oidcConfig.getIssuer()); } finally { client.close(); } } + @Test + public void corsTest() { + Client client = ClientBuilder.newClient(); + UriBuilder builder = UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT); + URI oidcDiscoveryUri = RealmsResource.wellKnownProviderUrl(builder).build("test", OIDCWellKnownProviderFactory.PROVIDER_ID); + WebTarget oidcDiscoveryTarget = client.target(oidcDiscoveryUri); + + + Invocation.Builder request = oidcDiscoveryTarget.request(); + request.header(Cors.ORIGIN_HEADER, "http://somehost"); + Response response = request.get(); + + assertEquals("*", response.getHeaders().getFirst(Cors.ACCESS_CONTROL_ALLOW_ORIGIN)); + } + private OIDCConfigurationRepresentation getOIDCDiscoveryConfiguration(Client client) { UriBuilder builder = UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT); URI oidcDiscoveryUri = RealmsResource.wellKnownProviderUrl(builder).build("test", OIDCWellKnownProviderFactory.PROVIDER_ID); WebTarget oidcDiscoveryTarget = client.target(oidcDiscoveryUri); Response response = oidcDiscoveryTarget.request().get(); + + assertEquals("no-cache, must-revalidate, no-transform, no-store", response.getHeaders().getFirst("Cache-Control")); + return response.readEntity(OIDCConfigurationRepresentation.class); }