keycloak-memoizeit

Details

diff --git a/integration/js/src/main/resources/keycloak.js b/integration/js/src/main/resources/keycloak.js
index c204f83..6c73ad5 100755
--- a/integration/js/src/main/resources/keycloak.js
+++ b/integration/js/src/main/resources/keycloak.js
@@ -89,6 +89,9 @@ var Keycloak = function (config) {
         kc.iframe.setAttribute('src', src );
         kc.iframe.style.display = "none";
         doc.body.appendChild(kc.iframe);
+        if (!kc.iframe.contentWindow.location.origin) {
+            kc.iframe.contentWindow.location.origin = kc.iframe.contentWindow.location.protocol + "//" + kc.iframe.contentWindow.location.host;
+        }
 
         var messageCallback = function(event) {
             if (event.origin !== kc.iframe.contentWindow.location.origin) {
@@ -114,6 +117,7 @@ var Keycloak = function (config) {
     }
 
     kc.checkLoginIframe = function(success, failure) {
+
         var msg = {};
         if (!success) {
             throw "You must define a success method";
@@ -125,7 +129,10 @@ var Keycloak = function (config) {
         msg.failureId = createCallbackId();
         kc.callbackMap[msg.successId] = success;
         kc.callbackMap[msg.failureId] = failure;
-        kc.iframe.contentWindow.postMessage(msg, kc.iframe.contentWindow.location.origin);
+        var origin = kc.iframe.contentWindow.location.origin;
+        console.log('*** origin: ' + origin);
+        var iframe = kc.iframe;
+        iframe.contentWindow.postMessage(msg, origin);
     }
 
     kc.createLoginUrl = function(options) {
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index ce5afb7..c3b9eec 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -21,6 +21,7 @@ import org.keycloak.services.resources.RealmsResource;
 import org.keycloak.authentication.AuthProviderStatus;
 import org.keycloak.authentication.AuthUser;
 import org.keycloak.authentication.AuthenticationProviderManager;
+import org.keycloak.services.util.CookieHelper;
 import org.keycloak.util.Time;
 
 import javax.ws.rs.core.Cookie;
@@ -89,22 +90,24 @@ public class AuthenticationManager {
             maxAge = realm.getCentralLoginLifespan();
             logger.info("createLoginCookie maxAge: " + maxAge);
         }
-        builder.cookie(new NewCookie(cookieName, encoded, cookiePath, null, null, maxAge, secureOnly));// todo httponly , true);
+        CookieHelper.addCookie(cookieName, encoded, cookiePath, null, null, maxAge, secureOnly, true);
+        //builder.cookie(new NewCookie(cookieName, encoded, cookiePath, null, null, maxAge, secureOnly));// todo httponly , true);
 
         String sessionCookieValue = realm.getName() + "-" + user.getId();
         if (session != null) {
             sessionCookieValue += "-" + session.getId();
         }
-        builder.cookie(new NewCookie(KEYCLOAK_SESSION_COOKIE, sessionCookieValue, cookiePath, null, null, maxAge, secureOnly));// todo httponly , true);
+        // THIS SHOULD NOT BE A HTTPONLY COOKIE!  It is used for OpenID Connect Iframe Session support!
+        builder.cookie(new NewCookie(KEYCLOAK_SESSION_COOKIE, sessionCookieValue, cookiePath, null, null, maxAge, secureOnly));
 
     }
 
-    public NewCookie createRememberMeCookie(RealmModel realm, UriInfo uriInfo) {
+    public void createRememberMeCookie(HttpResponse response, RealmModel realm, UriInfo uriInfo) {
         String path = getIdentityCookiePath(realm, uriInfo);
         boolean secureOnly = !realm.isSslNotRequired();
         // remember me cookie should be persistent
-        NewCookie cookie = new NewCookie(KEYCLOAK_REMEMBER_ME, "true", path, null, null, realm.getCentralLoginLifespan(), secureOnly);// todo httponly , true);
-        return cookie;
+        //NewCookie cookie = new NewCookie(KEYCLOAK_REMEMBER_ME, "true", path, null, null, realm.getCentralLoginLifespan(), secureOnly);// todo httponly , true);
+        CookieHelper.addCookie(KEYCLOAK_REMEMBER_ME, "true", path, null, null, realm.getCentralLoginLifespan(), secureOnly, true);
     }
 
     protected String encodeToken(RealmModel realm, Object token) {
@@ -117,15 +120,14 @@ public class AuthenticationManager {
     public void expireIdentityCookie(RealmModel realm, UriInfo uriInfo) {
         logger.debug("Expiring identity cookie");
         String path = getIdentityCookiePath(realm, uriInfo);
-        String cookieName = KEYCLOAK_IDENTITY_COOKIE;
-        expireCookie(cookieName, path);
-        expireCookie(KEYCLOAK_SESSION_COOKIE, path);
+        expireCookie(realm, KEYCLOAK_IDENTITY_COOKIE, path, true);
+        expireCookie(realm, KEYCLOAK_SESSION_COOKIE, path, false);
     }
     public void expireRememberMeCookie(RealmModel realm, UriInfo uriInfo) {
         logger.debug("Expiring remember me cookie");
         String path = getIdentityCookiePath(realm, uriInfo);
         String cookieName = KEYCLOAK_REMEMBER_ME;
-        expireCookie(cookieName, path);
+        expireCookie(realm, cookieName, path, true);
     }
 
     protected String getIdentityCookiePath(RealmModel realm, UriInfo uriInfo) {
@@ -133,15 +135,10 @@ public class AuthenticationManager {
         return uri.getRawPath();
     }
 
-    public void expireCookie(String cookieName, String path) {
-        HttpResponse response = ResteasyProviderFactory.getContextData(HttpResponse.class);
-        if (response == null) {
-            logger.debug("can't expire identity cookie, no HttpResponse");
-            return;
-        }
+    public void expireCookie(RealmModel realm, String cookieName, String path, boolean httpOnly) {
         logger.debugv("Expiring cookie: {0} path: {1}", cookieName, path);
-        NewCookie expireIt = new NewCookie(cookieName, "", path, null, "Expiring cookie", 0, false);
-        response.addNewCookie(expireIt);
+        boolean secureOnly = !realm.isSslNotRequired();
+        CookieHelper.addCookie(cookieName, "", path, null, "Expiring cookie", 0, secureOnly, httpOnly);
     }
 
     public AuthResult authenticateIdentityCookie(RealmModel realm, UriInfo uriInfo, HttpHeaders headers) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
index a063efa..889990f 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminConsole.java
@@ -258,6 +258,7 @@ public class AdminConsole {
     @Path("js/keycloak.js")
     @Produces("text/javascript")
     public Response getKeycloakJs() {
+        //logger.info("**** -> getting console keycloak.js" + " uri: " + uriInfo.getRequestUri().toString());
         InputStream inputStream = getClass().getClassLoader().getResourceAsStream("keycloak.js");
         if (inputStream != null) {
             return Response.ok(inputStream).build();
@@ -270,7 +271,15 @@ public class AdminConsole {
     @GET
     @Path("{path:.+}")
     public Response getResource(@PathParam("path") String path) {
+        // todo
+        // I don't know why I need this.  On IE 11, if I don't have this, getKeycloakJs() isn't invoked
+        // I just can't figure out what the difference is between IE11 and FF for console/js/keycloak.js calls
+        if (path.equals("js/keycloak.js")) {
+            return getKeycloakJs();
+        }
+
         try {
+            //logger.info("getting resource: " + path + " uri: " + uriInfo.getRequestUri().toString());
             String themeName = realm.getAdminTheme();
             if (themeName == null || themeName.trim().equals("")) {
                 themeName = Config.getThemeAdmin();
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
index c558d66..88b4be3 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java
@@ -92,12 +92,10 @@ public class AdminRoot {
 
     @Path("{realm}/console")
     public AdminConsole getAdminConsole(final @PathParam("realm") String name) {
-        logger.info("*** get console for realm: " + name);
         RealmManager realmManager = new RealmManager(session);
         RealmModel realm = locateRealm(name, realmManager);
         AdminConsole service = new AdminConsole(realm);
         ResteasyProviderFactory.getInstance().injectProperties(service);
-        logger.info("returning AdminConsole");
         return service;
     }
 
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 a5878d2..18c6caa 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -99,6 +99,7 @@ public class RealmsResource {
     @NoCache
     public String getLoginStatusIframe(final @PathParam("realm") String name,
                                        @QueryParam("client_id") String client_id) {
+        logger.info("getLoginStatusIframe");
         AuthenticationManager auth = new AuthenticationManager(providers);
 
         //logger.info("getting login-status-iframe.html for client_id: " + client_id);
diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java
index f70bceb..a262c83 100755
--- a/services/src/main/java/org/keycloak/services/resources/TokenService.java
+++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java
@@ -374,8 +374,7 @@ public class TokenService {
         AuthenticationStatus status = authManager.authenticateForm(clientConnection, realm, formData);
 
         if (remember) {
-            NewCookie cookie = authManager.createRememberMeCookie(realm, uriInfo);
-            response.addNewCookie(cookie);
+            authManager.createRememberMeCookie(response, realm, uriInfo);
         } else {
             authManager.expireRememberMeCookie(realm, uriInfo);
         }
diff --git a/services/src/main/java/org/keycloak/services/util/CookieHelper.java b/services/src/main/java/org/keycloak/services/util/CookieHelper.java
new file mode 100755
index 0000000..6d0d3a4
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/util/CookieHelper.java
@@ -0,0 +1,39 @@
+package org.keycloak.services.util;
+
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
+ * @version $Revision: 1 $
+ */
+public class CookieHelper {
+
+    /**
+     * Set a response cookie.  This solely exists because JAX-RS 1.1 does not support setting HttpOnly cookies
+     *
+     * @param name
+     * @param value
+     * @param path
+     * @param domain
+     * @param comment
+     * @param maxAge
+     * @param secure
+     * @param httpOnly
+     */
+    public static void addCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) {
+        HttpServletResponse response = ResteasyProviderFactory.getContextData(HttpServletResponse.class);
+        Cookie cookie = new Cookie(name, value);
+        if (path != null) cookie.setPath(path);
+        if (domain != null) cookie.setDomain(domain);
+        if (comment != null) cookie.setComment(comment);
+        cookie.setMaxAge(maxAge);
+        cookie.setSecure(secure);
+        cookie.setHttpOnly(httpOnly);
+
+        response.addCookie(cookie);
+
+    }
+}