keycloak-memoizeit

Merge pull request #3059 from mposolda/master KEYCLOAK-3354

7/22/2016 10:12:25 AM

Details

diff --git a/core/src/main/java/org/keycloak/OAuthErrorException.java b/core/src/main/java/org/keycloak/OAuthErrorException.java
index eb173f2..f0bb862 100755
--- a/core/src/main/java/org/keycloak/OAuthErrorException.java
+++ b/core/src/main/java/org/keycloak/OAuthErrorException.java
@@ -29,11 +29,13 @@ public class OAuthErrorException extends Exception {
     public static final String ACCESS_DENIED = "access_denied";
     public static final String UNSUPPORTED_RESPONSE_TYPE = "unsupported_response_type";
     public static final String SERVER_ERROR = "server_error";
-    public static final String TEMPORARILY_UNAVAILABKE = "temporarily_unavailable";
+    public static final String TEMPORARILY_UNAVAILABLE = "temporarily_unavailable";
 
     // OpenID Connect 1
     public static final String INTERACTION_REQUIRED = "interaction_required";
     public static final String LOGIN_REQUIRED = "login_required";
+    public static final String REQUEST_NOT_SUPPORTED = "request_not_supported";
+    public static final String REQUEST_URI_NOT_SUPPORTED = "request_uri_not_supported";
 
     // Others
     public static final String INVALID_CLIENT = "invalid_client";
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
index 2092079..1d88ac7 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
@@ -111,6 +111,7 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
 
     private Action action;
     private OIDCResponseType parsedResponseType;
+    private OIDCResponseMode parsedResponseMode;
 
     private String clientId;
     private String redirectUri;
@@ -162,6 +163,11 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
             logger.oidcScopeMissing();
         }
 
+        errorResponse = checkOIDCParams(params);
+        if (errorResponse != null) {
+            return errorResponse;
+        }
+
         createClientSession();
         // So back button doesn't work
         CacheControlUtil.noBackButtonCacheControlHeader();
@@ -313,6 +319,24 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
             return redirectErrorToClient(parsedResponseMode, OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE, "Client is not allowed to initiate browser login with given response_type. Implicit flow is disabled for the client.");
         }
 
+        this.parsedResponseMode = parsedResponseMode;
+
+        return null;
+    }
+
+    private Response checkOIDCParams(MultivaluedMap<String, String> params) {
+        if (params.getFirst(OIDCLoginProtocol.REQUEST_PARAM) != null) {
+            logger.unsupportedParameter(OIDCLoginProtocol.REQUEST_PARAM);
+            event.error(Errors.INVALID_REQUEST);
+            return redirectErrorToClient(parsedResponseMode, OAuthErrorException.REQUEST_NOT_SUPPORTED, null);
+        }
+
+        if (params.getFirst(OIDCLoginProtocol.REQUEST_URI_PARAM) != null) {
+            logger.unsupportedParameter(OIDCLoginProtocol.REQUEST_URI_PARAM);
+            event.error(Errors.INVALID_REQUEST);
+            return redirectErrorToClient(parsedResponseMode, OAuthErrorException.REQUEST_URI_NOT_SUPPORTED, null);
+        }
+
         return null;
     }
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
index 4391fba..a68dae8 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocol.java
@@ -63,6 +63,9 @@ public class OIDCLoginProtocol implements LoginProtocol {
     public static final String MAX_AGE_PARAM = OAuth2Constants.MAX_AGE;
     public static final String PROMPT_PARAM = OAuth2Constants.PROMPT;
     public static final String LOGIN_HINT_PARAM = "login_hint";
+    public static final String REQUEST_PARAM = "request";
+    public static final String REQUEST_URI_PARAM = "request_uri";
+
     public static final String LOGOUT_REDIRECT_URI = "OIDC_LOGOUT_REDIRECT_URI";
     public static final String ISSUER = "iss";
 
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 ddb4151..050795a 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCWellKnownProvider.java
@@ -102,6 +102,9 @@ public class OIDCWellKnownProvider implements WellKnownProvider {
 
         config.setScopesSupported(SCOPES_SUPPORTED);
 
+        config.setRequestParameterSupported(false);
+        config.setRequestUriParameterSupported(false);
+
         return config;
     }
 
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java b/services/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java
index 7f558b1..0421e16 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/representations/OIDCConfigurationRepresentation.java
@@ -88,6 +88,12 @@ public class OIDCConfigurationRepresentation {
     @JsonProperty("scopes_supported")
     private List<String> scopesSupported;
 
+    @JsonProperty("request_parameter_supported")
+    private Boolean requestParameterSupported;
+
+    @JsonProperty("request_uri_parameter_supported")
+    private Boolean requestUriParameterSupported;
+
     protected Map<String, Object> otherClaims = new HashMap<String, Object>();
 
     public String getIssuer() {
@@ -242,6 +248,22 @@ public class OIDCConfigurationRepresentation {
         this.scopesSupported = scopesSupported;
     }
 
+    public Boolean getRequestParameterSupported() {
+        return requestParameterSupported;
+    }
+
+    public void setRequestParameterSupported(Boolean requestParameterSupported) {
+        this.requestParameterSupported = requestParameterSupported;
+    }
+
+    public Boolean getRequestUriParameterSupported() {
+        return requestUriParameterSupported;
+    }
+
+    public void setRequestUriParameterSupported(Boolean requestUriParameterSupported) {
+        this.requestUriParameterSupported = requestUriParameterSupported;
+    }
+
     @JsonAnyGetter
     public Map<String, Object> getOtherClaims() {
         return otherClaims;
diff --git a/services/src/main/java/org/keycloak/services/ServicesLogger.java b/services/src/main/java/org/keycloak/services/ServicesLogger.java
index 7967e34..8aa4961 100644
--- a/services/src/main/java/org/keycloak/services/ServicesLogger.java
+++ b/services/src/main/java/org/keycloak/services/ServicesLogger.java
@@ -419,6 +419,10 @@ public interface ServicesLogger extends BasicLogger {
     void invalidParameter(String paramName);
 
     @LogMessage(level = ERROR)
-    @Message(id=94, value="Client is not allowed to initiate browser login with given response_type. %s flow is disabled for the client.")
+    @Message(id=94, value="Unsupported parameter: %s")
+    void unsupportedParameter(String paramName);
+
+    @LogMessage(level = ERROR)
+    @Message(id=95, value="Client is not allowed to initiate browser login with given response_type. %s flow is disabled for the client.")
     void flowNotAllowed(String flowName);
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java
index bdc582c..db691b2 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java
@@ -289,6 +289,78 @@ public class OIDCAdvancedRequestParamsTest extends TestRealmKeycloakTest {
     }
 
 
-    // prompt=consent
+    // NONCE
+
+    @Test
+    public void nonceNotUsed() {
+        driver.navigate().to(oauth.getLoginFormUrl());
+
+        loginPage.assertCurrent();
+        loginPage.login("test-user@localhost", "password");
+        Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+        EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent();
+        IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
+
+        Assert.assertNull(idToken.getNonce());
+    }
+
+    @Test
+    public void nonceMatches() {
+        driver.navigate().to(oauth.getLoginFormUrl() + "&nonce=abcdef123456");
+
+        loginPage.assertCurrent();
+        loginPage.login("test-user@localhost", "password");
+        Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+        EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent();
+        IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
+
+        Assert.assertEquals("abcdef123456", idToken.getNonce());
+    }
+
+    // DISPLAY & OTHERS
+
+    @Test
+    public void nonSupportedParams() {
+        driver.navigate().to(oauth.getLoginFormUrl() + "&display=popup&foo=foobar");
+
+        loginPage.assertCurrent();
+        loginPage.login("test-user@localhost", "password");
+        Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
+
+        EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent();
+        IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent);
+
+        Assert.assertNotNull(idToken);
+    }
+
+    // REQUEST & REQUEST_URI
+
+    @Test
+    public void requestParam() {
+        driver.navigate().to(oauth.getLoginFormUrl() + "&request=abc");
+
+        assertFalse(loginPage.isCurrent());
+        assertTrue(appPage.isCurrent());
+
+        // Assert error response was sent because not logged in
+        OAuthClient.AuthorizationCodeResponse resp = new OAuthClient.AuthorizationCodeResponse(oauth);
+        Assert.assertNull(resp.getCode());
+        Assert.assertEquals(OAuthErrorException.REQUEST_NOT_SUPPORTED, resp.getError());
+    }
+
+    @Test
+    public void requestUriParam() {
+        driver.navigate().to(oauth.getLoginFormUrl() + "&request_uri=https%3A%2F%2Flocalhost%3A60784%2Fexport%2FqzHTG11W48.jwt");
+
+        assertFalse(loginPage.isCurrent());
+        assertTrue(appPage.isCurrent());
+
+        // Assert error response was sent because not logged in
+        OAuthClient.AuthorizationCodeResponse resp = new OAuthClient.AuthorizationCodeResponse(oauth);
+        Assert.assertNull(resp.getCode());
+        Assert.assertEquals(OAuthErrorException.REQUEST_URI_NOT_SUPPORTED, resp.getError());
+    }
 
 }
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 24188fc..ab5c230 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
@@ -98,6 +98,10 @@ public class OIDCWellKnownProviderTest extends AbstractKeycloakTest {
 
             // Scopes supported
             Assert.assertNames(oidcConfig.getScopesSupported(), OAuth2Constants.SCOPE_OPENID, OAuth2Constants.OFFLINE_ACCESS);
+
+            // Request and Request_Uri
+            Assert.assertFalse(oidcConfig.getRequestParameterSupported());
+            Assert.assertFalse(oidcConfig.getRequestUriParameterSupported());
         } finally {
             client.close();
         }