diff --git a/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCRedirectUriBuilder.java b/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCRedirectUriBuilder.java
index d09bc47bb1..95de1b9b96 100644
--- a/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCRedirectUriBuilder.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/utils/OIDCRedirectUriBuilder.java
@@ -125,7 +125,7 @@ public abstract class OIDCRedirectUriBuilder {
@Override
public OIDCRedirectUriBuilder addParam(String paramName, String paramValue) {
- params.put(paramName, Encode.encodeQueryParam(paramValue));
+ params.put(paramName, paramValue);
return this;
}
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java
index f75d93c68c..bc63c99f70 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestApplicationResourceProvider.java
@@ -17,6 +17,8 @@
package org.keycloak.testsuite.rest;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.models.KeycloakSession;
@@ -25,7 +27,6 @@ import org.keycloak.representations.adapters.action.PushNotBeforeAction;
import org.keycloak.representations.adapters.action.TestAvailabilityAction;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resources.RealmsResource;
-import org.keycloak.testsuite.events.EventsListenerProvider;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -34,8 +35,10 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
+
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -110,6 +113,35 @@ public class TestApplicationResourceProvider implements RealmResourceProvider {
return Response.noContent().build();
}
+ @POST
+ @Produces(MediaType.TEXT_HTML)
+ @Path("/{action}")
+ public String post(@PathParam("action") String action) {
+ String title = "APP_REQUEST";
+ if (action.equals("auth")) {
+ title = "AUTH_RESPONSE";
+ } else if (action.equals("logout")) {
+ title = "LOGOUT_REQUEST";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("
" + title + "");
+
+ sb.append("Form parameters:
");
+ HttpRequest request = ResteasyProviderFactory.getContextData(HttpRequest.class);
+ MultivaluedMap formParams = request.getDecodedFormParameters();
+ for (String paramName : formParams.keySet()) {
+ sb.append(paramName).append(": ").append("").append(formParams.getFirst(paramName)).append("
");
+ }
+ sb.append("
");
+
+ UriBuilder base = UriBuilder.fromUri("http://localhost:8180/auth");
+ sb.append("account");
+
+ sb.append("");
+ return sb.toString();
+ }
+
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/{action}")
diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
index cbfcc5beba..be9127dc9d 100644
--- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
+++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/OAuthClient.java
@@ -36,9 +36,6 @@ import org.keycloak.admin.client.Keycloak;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.PemUtils;
import org.keycloak.constants.AdapterConstants;
-import org.keycloak.jose.jwk.JWK;
-import org.keycloak.jose.jwk.JWKBuilder;
-import org.keycloak.jose.jwk.JWKParser;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.crypto.RSAProvider;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
@@ -99,6 +96,10 @@ public class OAuthClient {
private String maxAge;
+ private String responseType = OAuth2Constants.CODE;
+
+ private String responseMode;
+
private Map publicKeys = new HashMap<>();
public void init(Keycloak adminClient, WebDriver driver) {
@@ -486,7 +487,12 @@ public class OAuthClient {
public String getLoginFormUrl() {
UriBuilder b = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(AUTH_SERVER_ROOT));
- b.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE);
+ if (responseType != null) {
+ b.queryParam(OAuth2Constants.RESPONSE_TYPE, responseType);
+ }
+ if (responseMode != null) {
+ b.queryParam(OIDCLoginProtocol.RESPONSE_MODE_PARAM, responseMode);
+ }
if (clientId != null) {
b.queryParam(OAuth2Constants.CLIENT_ID, clientId);
}
@@ -598,6 +604,16 @@ public class OAuthClient {
return this;
}
+ public OAuthClient responseType(String responseType) {
+ this.responseType = responseType;
+ return this;
+ }
+
+ public OAuthClient responseMode(String responseMode) {
+ this.responseMode = responseMode;
+ return this;
+ }
+
public String getRealm() {
return realm;
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
index 3fc08b4640..a5082c5217 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java
@@ -18,12 +18,14 @@ package org.keycloak.testsuite.oauth;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.models.Constants;
+import org.keycloak.protocol.oidc.utils.OIDCResponseMode;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.AssertEvents;
@@ -65,15 +67,21 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest {
}
+ @Before
+ public void clientConfiguration() {
+ oauth.responseType(OAuth2Constants.CODE);
+ oauth.responseMode(null);
+ }
+
@Test
public void authorizationRequest() throws IOException {
- oauth.state("mystate");
+ oauth.state("OpenIdConnect.AuthenticationProperties=2302984sdlk");
OAuthClient.AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
Assert.assertTrue(response.isRedirected());
Assert.assertNotNull(response.getCode());
- assertEquals("mystate", response.getState());
+ assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", response.getState());
Assert.assertNull(response.getError());
testingClient.testing().verifyCode("test", response.getCode());
@@ -137,8 +145,8 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest {
@Test
public void authorizationRequestImplicitFlowDisabled() throws IOException {
+ oauth.responseType("token id_token");
UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl());
- b.replaceQueryParam(OAuth2Constants.RESPONSE_TYPE, "token id_token");
driver.navigate().to(b.build().toURL());
assertEquals("Client is not allowed to initiate browser login with given response_type. Implicit flow is disabled for the client.", errorPage.getError());
events.expectLogin().error(Errors.NOT_ALLOWED).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "token id_token").assertEvent();
@@ -146,13 +154,33 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest {
@Test
public void authorizationRequestInvalidResponseType() throws IOException {
+ oauth.responseType("tokenn");
UriBuilder b = UriBuilder.fromUri(oauth.getLoginFormUrl());
- 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, "tokenn").assertEvent();
}
+ // KEYCLOAK-3281
+ @Test
+ public void authorizationRequestFormPostResponseMode() throws IOException {
+ oauth.responseMode(OIDCResponseMode.FORM_POST.toString().toLowerCase());
+ oauth.state("OpenIdConnect.AuthenticationProperties=2302984sdlk");
+ oauth.doLoginGrant("test-user@localhost", "password");
+
+ String sources = driver.getPageSource();
+ System.out.println(sources);
+
+ String code = driver.findElement(By.id("code")).getText();
+ String state = driver.findElement(By.id("state")).getText();
+
+ assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", state);
+
+ testingClient.testing().verifyCode("test", code);
+ String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID);
+ assertCode(codeId, code);
+ }
+
private void assertCode(String expectedCodeId, String actualCode) {
String code = testingClient.testing().verifyCode("test", actualCode);
assertEquals(expectedCodeId, code);