keycloak-aplcache

Merge pull request #2110 from mposolda/master KEYCLOAK-2351

1/26/2016 2:54:08 PM

Details

diff --git a/docbook/auth-server-docs/reference/en/en-US/modules/application-clustering.xml b/docbook/auth-server-docs/reference/en/en-US/modules/application-clustering.xml
index c4246d2..5dab883 100644
--- a/docbook/auth-server-docs/reference/en/en-US/modules/application-clustering.xml
+++ b/docbook/auth-server-docs/reference/en/en-US/modules/application-clustering.xml
@@ -28,6 +28,14 @@
         and his browser and hence can't rely on sticky sessions.
     </para>
 
+    <note>
+        <para>
+            To enable distributable (replicated) HTTP Sessions in your application, you may need to do some additional steps. Usually you need to put <![CDATA[<distributable />]]>
+            tag into <literal>WEB-INF/web.xml</literal> file of your application and possibly do some additional steps to configure underlying cluster cache (In case of
+            Wildfly, the implementation of cluster cache is based on Infinispan). These steps are server specific, so consult documentation of your application server for more details.
+        </para>
+    </note>
+
     <section id="stateless-token-store">
         <title>Stateless token store</title>
         <para>
diff --git a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
index 4cb728f..a1a847d 100644
--- a/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
+++ b/services/src/main/java/org/keycloak/authentication/authenticators/client/JWTClientAuthenticator.java
@@ -2,6 +2,7 @@ package org.keycloak.authentication.authenticators.client;
 
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -120,7 +121,7 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator {
             // Validate other things
             String expectedAudience = Urls.realmIssuer(context.getUriInfo().getBaseUri(), realm.getName());
             if (!token.hasAudience(expectedAudience)) {
-                throw new RuntimeException("Token audience doesn't match domain. Realm audience is '" + expectedAudience + "' but audience from token is '" + token.getAudience() + "'");
+                throw new RuntimeException("Token audience doesn't match domain. Realm audience is '" + expectedAudience + "' but audience from token is '" + Arrays.asList(token.getAudience()).toString() + "'");
             }
 
             if (!token.isActive()) {
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
index 8e0cdbf..4f6a5cc 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
@@ -26,7 +26,7 @@ public class OIDCWellKnownProvider implements WellKnownProvider {
 
     public static final List<String> DEFAULT_GRANT_TYPES_SUPPORTED = list(OAuth2Constants.AUTHORIZATION_CODE, OAuth2Constants.IMPLICIT, OAuth2Constants.REFRESH_TOKEN, OAuth2Constants.PASSWORD, OAuth2Constants.CLIENT_CREDENTIALS);
 
-    public static final List<String> DEFAULT_RESPONSE_TYPES_SUPPORTED = list(OAuth2Constants.CODE, OIDCResponseType.NONE, OIDCResponseType.ID_TOKEN, "id_token token", "code id_token", "code token", "code id_token token");
+    public static final List<String> DEFAULT_RESPONSE_TYPES_SUPPORTED = list(OAuth2Constants.CODE, OIDCResponseType.NONE, OIDCResponseType.ID_TOKEN, OIDCResponseType.TOKEN, "id_token token", "code id_token", "code token", "code id_token token");
 
     public static final List<String> DEFAULT_SUBJECT_TYPES_SUPPORTED = list("public");
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCResponseType.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCResponseType.java
index 9313aa6..e8327ec 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCResponseType.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCResponseType.java
@@ -63,9 +63,11 @@ public class OIDCResponseType {
         if (responseTypes.contains(NONE) && responseTypes.size() > 1) {
             throw new IllegalArgumentException("None not allowed with some other response_type");
         }
-        if (responseTypes.contains(TOKEN) && responseTypes.size() == 1) {
-            throw new IllegalArgumentException("Not supported to use response_type=token alone");
-        }
+
+        // response_type value "token" alone is not mentioned in OIDC specification, however it is supported by OAuth2. We allow it just to be compatible with pure OAuth2 clients like swagger.ui
+//        if (responseTypes.contains(TOKEN) && responseTypes.size() == 1) {
+//            throw new IllegalArgumentException("Not supported to use response_type=token alone");
+//        }
     }
 
 
@@ -79,7 +81,7 @@ public class OIDCResponseType {
     }
 
     public boolean isImplicitFlow() {
-        return hasResponseType(ID_TOKEN) && !hasResponseType(CODE);
+        return (hasResponseType(TOKEN) || hasResponseType(ID_TOKEN)) && !hasResponseType(CODE);
     }
 
 
diff --git a/services/src/test/java/org/keycloak/test/ResponseTypeTest.java b/services/src/test/java/org/keycloak/test/ResponseTypeTest.java
index dd15aa9..42d852a 100644
--- a/services/src/test/java/org/keycloak/test/ResponseTypeTest.java
+++ b/services/src/test/java/org/keycloak/test/ResponseTypeTest.java
@@ -20,7 +20,7 @@ public class ResponseTypeTest {
         assertSuccess("code");
         assertSuccess("none");
         assertSuccess("id_token");
-        assertFail("token");
+        assertSuccess("token");
         assertFail("refresh_token");
         assertSuccess("id_token token");
         assertSuccess("code token");
@@ -32,13 +32,13 @@ public class ResponseTypeTest {
 
     @Test
     public void testMultipleResponseTypes() {
-        try {
-            OIDCResponseType.parse(Arrays.asList("code", "token"));
-            Assert.fail("Not expected to parse with success");
-        } catch (IllegalArgumentException iae) {
-        }
+        OIDCResponseType responseType = OIDCResponseType.parse(Arrays.asList("code", "token"));
+        Assert.assertTrue(responseType.hasResponseType("code"));
+        Assert.assertFalse(responseType.hasResponseType("none"));
+        Assert.assertTrue(responseType.isImplicitOrHybridFlow());
+        Assert.assertFalse(responseType.isImplicitFlow());
 
-        OIDCResponseType responseType = OIDCResponseType.parse(Collections.singletonList("code"));
+        responseType = OIDCResponseType.parse(Collections.singletonList("code"));
         Assert.assertTrue(responseType.hasResponseType("code"));
         Assert.assertFalse(responseType.hasResponseType("none"));
         Assert.assertFalse(responseType.isImplicitOrHybridFlow());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
index 12d443a..232c578 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
@@ -171,10 +171,10 @@ public class AuthorizationCodeTest {
     @Test
     public void authorizationRequestInvalidResponseType() throws IOException {
         UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl());
-        b.replaceQueryParam(OAuth2Constants.RESPONSE_TYPE, "token");
+        b.replaceQueryParam(OAuth2Constants.RESPONSE_TYPE, "tokenn");
         driver.navigate().to(b.build().toURL());
         assertEquals("Invalid parameter: response_type", errorPage.getError());
-        events.expectLogin().error(Errors.INVALID_REQUEST).client((String) null).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "token").assertEvent();
+        events.expectLogin().error(Errors.INVALID_REQUEST).client((String) null).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent();
     }
 
     private void assertCode(String expectedCodeId, String actualCode) {
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/OIDCClientRegistrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/OIDCClientRegistrationTest.java
index f0fbe2b..81a69af 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/OIDCClientRegistrationTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/OIDCClientRegistrationTest.java
@@ -90,7 +90,7 @@ public class OIDCClientRegistrationTest extends AbstractClientRegistrationTest {
         try {
             OIDCClientRepresentation response = create();
             reg.auth(Auth.token(response));
-            response.setResponseTypes(Arrays.asList("code", "token"));
+            response.setResponseTypes(Arrays.asList("code", "tokenn"));
             reg.oidc().update(response);
             fail("Not expected to end with success");
         } catch (ClientRegistrationException cre) {