Merge pull request #3620 from patriot1burke/master

KEYCLOAK-3509
This commit is contained in:
Bill Burke 2016-12-06 20:08:36 -05:00 committed by GitHub
commit d163dad3fe
12 changed files with 80 additions and 4 deletions

View file

@ -25,6 +25,7 @@ import org.keycloak.adapters.spi.AuthChallenge;
import org.keycloak.adapters.spi.AuthOutcome; import org.keycloak.adapters.spi.AuthOutcome;
import org.keycloak.adapters.spi.HttpFacade; import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.common.VerificationException; import org.keycloak.common.VerificationException;
import org.keycloak.common.util.Encode;
import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.common.util.UriUtils; import org.keycloak.common.util.UriUtils;
import org.keycloak.constants.AdapterConstants; import org.keycloak.constants.AdapterConstants;
@ -169,7 +170,7 @@ public class OAuthRequestAuthenticator {
KeycloakUriBuilder redirectUriBuilder = deployment.getAuthUrl().clone() KeycloakUriBuilder redirectUriBuilder = deployment.getAuthUrl().clone()
.queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE) .queryParam(OAuth2Constants.RESPONSE_TYPE, OAuth2Constants.CODE)
.queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName()) .queryParam(OAuth2Constants.CLIENT_ID, deployment.getResourceName())
.queryParam(OAuth2Constants.REDIRECT_URI, url) .queryParam(OAuth2Constants.REDIRECT_URI, Encode.encodeQueryParamAsIs(url)) // Need to encode uri ourselves as queryParam() will not encode % characters.
.queryParam(OAuth2Constants.STATE, state) .queryParam(OAuth2Constants.STATE, state)
.queryParam("login", "true"); .queryParam("login", "true");
if(loginHint != null && loginHint.length() > 0){ if(loginHint != null && loginHint.length() > 0){

View file

@ -89,7 +89,7 @@ public class AuthorizationEndpoint extends AuthorizationEndpointBase {
@GET @GET
public Response build() { public Response build() {
MultivaluedMap<String, String> params = uriInfo.getQueryParameters(); MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
String requestUri = uriInfo.getRequestUri().toString();
String clientId = params.getFirst(OIDCLoginProtocol.CLIENT_ID_PARAM); String clientId = params.getFirst(OIDCLoginProtocol.CLIENT_ID_PARAM);
checkSsl(); checkSsl();

View file

@ -245,7 +245,8 @@ public class TokenEndpoint {
event.session(userSession.getId()); event.session(userSession.getId());
String redirectUri = clientSession.getNote(OIDCLoginProtocol.REDIRECT_URI_PARAM); String redirectUri = clientSession.getNote(OIDCLoginProtocol.REDIRECT_URI_PARAM);
if (redirectUri != null && !redirectUri.equals(formParams.getFirst(OAuth2Constants.REDIRECT_URI))) { String formParam = formParams.getFirst(OAuth2Constants.REDIRECT_URI);
if (redirectUri != null && !redirectUri.equals(formParam)) {
event.error(Errors.INVALID_CODE); event.error(Errors.INVALID_CODE);
throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "Incorrect redirect_uri", Response.Status.BAD_REQUEST); throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "Incorrect redirect_uri", Response.Status.BAD_REQUEST);
} }

View file

@ -19,6 +19,8 @@ package org.keycloak.testsuite.adapter;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.common.util.Encode;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
@ -98,6 +100,11 @@ public class AdapterTest {
testStrategy.testLoginSSOAndLogout(); testStrategy.testLoginSSOAndLogout();
} }
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test @Test
public void testSavedPostRequest() throws Exception { public void testSavedPostRequest() throws Exception {
testStrategy.testSavedPostRequest(); testStrategy.testSavedPostRequest();

View file

@ -216,6 +216,36 @@ public class AdapterTestStrategy extends ExternalResource {
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL)); Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
} }
/**
* KEYCLOAK-3509
*
* @throws Exception
*/
public void testLoginEncodedRedirectUri() throws Exception {
// test login to customer-portal which does a bearer request to customer-db
driver.navigate().to(APP_SERVER_BASE_URL + "/product-portal?encodeTest=a%3Cb");
System.out.println("Current url: " + driver.getCurrentUrl());
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
loginPage.login("bburke@redhat.com", "password");
System.out.println("Current url: " + driver.getCurrentUrl());
Assert.assertEquals(driver.getCurrentUrl(), APP_SERVER_BASE_URL + "/product-portal?encodeTest=a%3Cb");
String pageSource = driver.getPageSource();
System.out.println(pageSource);
Assert.assertTrue(pageSource.contains("iPhone"));
Assert.assertTrue(pageSource.contains("uriEncodeTest=true"));
// test logout
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(AUTH_SERVER_URL))
.queryParam(OAuth2Constants.REDIRECT_URI, APP_SERVER_BASE_URL + "/product-portal").build("demo").toString();
driver.navigate().to(logoutUri);
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
driver.navigate().to(APP_SERVER_BASE_URL + "/product-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
}
public void testServletRequestLogout() throws Exception { public void testServletRequestLogout() throws Exception {
// test login to customer-portal which does a bearer request to customer-db // test login to customer-portal which does a bearer request to customer-db
driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal"); driver.navigate().to(APP_SERVER_BASE_URL + "/customer-portal");

View file

@ -38,6 +38,9 @@ public class ProductServlet extends HttpServlet {
pw.printf("<html><head><title>%s</title></head><body>", "Product Portal"); pw.printf("<html><head><title>%s</title></head><body>", "Product Portal");
pw.println("iPhone"); pw.println("iPhone");
pw.println("iPad"); pw.println("iPad");
String x = req.getParameter("encodeTest");
String encodeTest= Boolean.toString("a<b".equals(x));
pw.println("uriEncodeTest=" + encodeTest);
pw.print("</body></html>"); pw.print("</body></html>");
pw.flush(); pw.flush();

View file

@ -100,6 +100,12 @@ public class Jetty9Test {
testStrategy.testLoginSSOAndLogout(); testStrategy.testLoginSSOAndLogout();
} }
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test @Test
public void testServletRequestLogout() throws Exception { public void testServletRequestLogout() throws Exception {
testStrategy.testServletRequestLogout(); testStrategy.testServletRequestLogout();

View file

@ -95,6 +95,12 @@ public class Jetty9Test {
testStrategy.testLoginSSOAndLogout(); testStrategy.testLoginSSOAndLogout();
} }
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test @Test
public void testSavedPostRequest() throws Exception { public void testSavedPostRequest() throws Exception {
testStrategy.testSavedPostRequest(); testStrategy.testSavedPostRequest();

View file

@ -95,6 +95,12 @@ public class Jetty9Test {
testStrategy.testLoginSSOAndLogout(); testStrategy.testLoginSSOAndLogout();
} }
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test @Test
public void testSavedPostRequest() throws Exception { public void testSavedPostRequest() throws Exception {
testStrategy.testSavedPostRequest(); testStrategy.testSavedPostRequest();

View file

@ -79,6 +79,10 @@ public class TomcatTest {
public void testLoginSSOAndLogout() throws Exception { public void testLoginSSOAndLogout() throws Exception {
testStrategy.testLoginSSOAndLogout(); testStrategy.testLoginSSOAndLogout();
} }
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test @Test
public void testSavedPostRequest() throws Exception { public void testSavedPostRequest() throws Exception {

View file

@ -83,6 +83,12 @@ public class Tomcat7Test {
testStrategy.testLoginSSOAndLogout(); testStrategy.testLoginSSOAndLogout();
} }
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test @Test
public void testSavedPostRequest() throws Exception { public void testSavedPostRequest() throws Exception {
testStrategy.testSavedPostRequest(); testStrategy.testSavedPostRequest();

View file

@ -83,6 +83,12 @@ public class TomcatTest {
testStrategy.testLoginSSOAndLogout(); testStrategy.testLoginSSOAndLogout();
} }
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test @Test
public void testSavedPostRequest() throws Exception { public void testSavedPostRequest() throws Exception {
testStrategy.testSavedPostRequest(); testStrategy.testSavedPostRequest();