diff --git a/common/src/main/java/org/keycloak/common/util/UriUtils.java b/common/src/main/java/org/keycloak/common/util/UriUtils.java index 8668bc2644..716b024a46 100755 --- a/common/src/main/java/org/keycloak/common/util/UriUtils.java +++ b/common/src/main/java/org/keycloak/common/util/UriUtils.java @@ -104,7 +104,7 @@ public class UriUtils { String protocol = parsed.getProtocol().toLowerCase(); - if (!("http".equalsIgnoreCase(protocol) || "https".equalsIgnoreCase(protocol))) { + if (!("http".equals(protocol) || "https".equals(protocol))) { throw new IllegalArgumentException("Invalid protocol/scheme for url [" + name + "]"); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java index 2274d6cbd7..64195a83be 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java @@ -165,7 +165,13 @@ public class IdentityProviderResource { return Response.noContent().build(); } catch (IllegalArgumentException e) { - return ErrorResponse.error("Invalid request", BAD_REQUEST); + String message = e.getMessage(); + + if (message == null) { + message = "Invalid request"; + } + + return ErrorResponse.error(message, BAD_REQUEST); } catch (ModelDuplicateException e) { return ErrorResponse.exists("Identity Provider " + providerRep.getAlias() + " already exists"); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java index e1103621a5..388672f5a2 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java @@ -198,7 +198,13 @@ public class IdentityProvidersResource { return Response.created(session.getContext().getUri().getAbsolutePathBuilder().path(representation.getAlias()).build()).build(); } catch (IllegalArgumentException e) { - return ErrorResponse.error("Invalid request", BAD_REQUEST); + String message = e.getMessage(); + + if (message == null) { + message = "Invalid request"; + } + + return ErrorResponse.error(message, BAD_REQUEST); } catch (ModelDuplicateException e) { return ErrorResponse.exists("Identity Provider " + representation.getAlias() + " already exists"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java index 5d1e6df46b..4be0c56a6e 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java @@ -36,6 +36,7 @@ import org.keycloak.models.utils.StripSecretsUtils; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.ComponentRepresentation; +import org.keycloak.representations.idm.ErrorRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; @@ -183,6 +184,8 @@ public class IdentityProviderTest extends AbstractAdminTest { try (Response response = this.realm.identityProviders().create(newIdentityProvider)) { assertEquals(AUTH_SERVER_SSL_REQUIRED ? Response.Status.BAD_REQUEST.getStatusCode() : Response.Status.CREATED.getStatusCode(), response.getStatus()); + ErrorRepresentation error = response.readEntity(ErrorRepresentation.class); + assertEquals("The url [authorization_url] is malformed", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -191,6 +194,8 @@ public class IdentityProviderTest extends AbstractAdminTest { try (Response response = this.realm.identityProviders().create(newIdentityProvider)) { assertEquals(AUTH_SERVER_SSL_REQUIRED ? Response.Status.BAD_REQUEST.getStatusCode() : Response.Status.CREATED.getStatusCode(), response.getStatus()); + ErrorRepresentation error = response.readEntity(ErrorRepresentation.class); + assertEquals("The url [token_url] requires secure connections", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -200,6 +205,8 @@ public class IdentityProviderTest extends AbstractAdminTest { try (Response response = this.realm.identityProviders().create(newIdentityProvider)) { assertEquals(AUTH_SERVER_SSL_REQUIRED ? Response.Status.BAD_REQUEST.getStatusCode() : Response.Status.CREATED.getStatusCode(), response.getStatus()); + ErrorRepresentation error = response.readEntity(ErrorRepresentation.class); + assertEquals("The url [jwks_url] requires secure connections", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -210,6 +217,8 @@ public class IdentityProviderTest extends AbstractAdminTest { try (Response response = this.realm.identityProviders().create(newIdentityProvider)) { assertEquals(AUTH_SERVER_SSL_REQUIRED ? Response.Status.BAD_REQUEST.getStatusCode() : Response.Status.CREATED.getStatusCode(), response.getStatus()); + ErrorRepresentation error = response.readEntity(ErrorRepresentation.class); + assertEquals("The url [logout_url] requires secure connections", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -221,6 +230,8 @@ public class IdentityProviderTest extends AbstractAdminTest { try (Response response = this.realm.identityProviders().create(newIdentityProvider)) { assertEquals(AUTH_SERVER_SSL_REQUIRED ? Response.Status.BAD_REQUEST.getStatusCode() : Response.Status.CREATED.getStatusCode(), response.getStatus()); + ErrorRepresentation error = response.readEntity(ErrorRepresentation.class); + assertEquals("The url [userinfo_url] requires secure connections", error.getErrorMessage()); } } } @@ -365,7 +376,10 @@ public class IdentityProviderTest extends AbstractAdminTest { fail("Invalid URL"); } catch (Exception e) { assertTrue(e instanceof ClientErrorException); - assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), ClientErrorException.class.cast(e).getResponse().getStatus()); + Response response = ClientErrorException.class.cast(e).getResponse(); + assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + ErrorRepresentation error = ((ClientErrorException) e).getResponse().readEntity(ErrorRepresentation.class); + assertEquals("The url [authorization_url] is malformed", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -376,7 +390,10 @@ public class IdentityProviderTest extends AbstractAdminTest { fail("Invalid URL"); } catch (Exception e) { assertTrue(e instanceof ClientErrorException); - assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), ClientErrorException.class.cast(e).getResponse().getStatus()); + Response response = ClientErrorException.class.cast(e).getResponse(); + assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + ErrorRepresentation error = ((ClientErrorException) e).getResponse().readEntity(ErrorRepresentation.class); + assertEquals("The url [token_url] requires secure connections", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -387,7 +404,10 @@ public class IdentityProviderTest extends AbstractAdminTest { fail("Invalid URL"); } catch (Exception e) { assertTrue(e instanceof ClientErrorException); - assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), ClientErrorException.class.cast(e).getResponse().getStatus()); + Response response = ClientErrorException.class.cast(e).getResponse(); + assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + ErrorRepresentation error = ((ClientErrorException) e).getResponse().readEntity(ErrorRepresentation.class); + assertEquals("The url [jwks_url] requires secure connections", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -399,7 +419,10 @@ public class IdentityProviderTest extends AbstractAdminTest { fail("Invalid URL"); } catch (Exception e) { assertTrue(e instanceof ClientErrorException); - assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), ClientErrorException.class.cast(e).getResponse().getStatus()); + Response response = ClientErrorException.class.cast(e).getResponse(); + assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + ErrorRepresentation error = ((ClientErrorException) e).getResponse().readEntity(ErrorRepresentation.class); + assertEquals("The url [logout_url] requires secure connections", error.getErrorMessage()); } oidcConfig.setAuthorizationUrl(null); @@ -413,7 +436,10 @@ public class IdentityProviderTest extends AbstractAdminTest { fail("Invalid URL"); } catch (Exception e) { assertTrue(e instanceof ClientErrorException); - assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), ClientErrorException.class.cast(e).getResponse().getStatus()); + Response response = ClientErrorException.class.cast(e).getResponse(); + assertEquals( Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + ErrorRepresentation error = ((ClientErrorException) e).getResponse().readEntity(ErrorRepresentation.class); + assertEquals("The url [userinfo_url] requires secure connections", error.getErrorMessage()); } rau.updateWith(r -> r.setSslRequired(SslRequired.EXTERNAL.name())).update();