diff --git a/adapters/oidc/js/src/main/resources/login-status-iframe-deprecated.html b/adapters/oidc/js/src/main/resources/login-status-iframe-deprecated.html new file mode 100755 index 0000000000..01515e3025 --- /dev/null +++ b/adapters/oidc/js/src/main/resources/login-status-iframe-deprecated.html @@ -0,0 +1,49 @@ + + + \ No newline at end of file diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java index bfa4c299b9..d1fc565ee9 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/LoginStatusIframeEndpoint.java @@ -17,22 +17,24 @@ package org.keycloak.protocol.oidc.endpoints; +import org.keycloak.Config; +import org.keycloak.common.util.StreamUtil; import org.keycloak.common.util.UriUtils; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; +import org.keycloak.protocol.oidc.utils.RedirectUtils; import org.keycloak.protocol.oidc.utils.WebOriginsUtils; import org.keycloak.services.util.CacheControlUtil; import org.keycloak.services.util.P3PHelper; import org.keycloak.utils.MediaType; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; +import javax.ws.rs.*; +import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; +import java.io.IOException; import java.io.InputStream; import java.util.Set; @@ -55,7 +57,12 @@ public class LoginStatusIframeEndpoint { @GET @Produces(MediaType.TEXT_HTML_UTF_8) - public Response getLoginStatusIframe() { + public Response getLoginStatusIframe(@QueryParam("client_id") String client_id, + @QueryParam("origin") String origin) { + if (client_id != null && origin != null) { + return getLoginStatusIframeDeprecated(client_id, origin); + } + InputStream resource = getClass().getClassLoader().getResourceAsStream("login-status-iframe.html"); if (resource != null) { P3PHelper.addP3PHeader(session); @@ -83,4 +90,60 @@ public class LoginStatusIframeEndpoint { return Response.status(Response.Status.FORBIDDEN).build(); } + // Support for old keycloak.js + private Response getLoginStatusIframeDeprecated(@QueryParam("client_id") String client_id, + @QueryParam("origin") String origin) { + if (!UriUtils.isOrigin(origin)) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } + + ClientModel client = realm.getClientByClientId(client_id); + if (client == null) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } + + InputStream is = getClass().getClassLoader().getResourceAsStream("login-status-iframe-deprecated.html"); + if (is == null) throw new org.jboss.resteasy.spi.NotFoundException("Could not find login-status-iframe-deprecated.html "); + + boolean valid = false; + for (String o : client.getWebOrigins()) { + if (o.equals("*") || o.equals(origin)) { + valid = true; + break; + } + } + + for (String r : RedirectUtils.resolveValidRedirects(uriInfo, client.getRootUrl(), client.getRedirectUris())) { + int i = r.indexOf('/', 8); + if (i != -1) { + r = r.substring(0, i); + } + + if (r.equals(origin)) { + valid = true; + break; + } + } + + if (!valid) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } + + try { + String file = StreamUtil.readString(is); + file = file.replace("ORIGIN", origin); + + P3PHelper.addP3PHeader(session); + + CacheControl cacheControl = new CacheControl(); + cacheControl.setNoTransform(false); + cacheControl.setMaxAge(Config.scope("theme").getInt("staticMaxAge", -1)); + + return Response.ok(file).cacheControl(cacheControl).build(); + } catch (IOException e) { + throw new WebApplicationException(e, Response.Status.BAD_REQUEST); + } + } + + }