Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Bill Burke 2018-03-02 11:29:13 -05:00
commit cc24484eaf
134 changed files with 1127 additions and 1786 deletions

View file

@ -34,7 +34,7 @@ import javax.persistence.UniqueConstraint;
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/ */
@Entity @Entity
@Table(name = "RESOURCE_SERVER_PERMISSION_TICKET", uniqueConstraints = { @Table(name = "RESOURCE_SERVER_PERM_TICKET", uniqueConstraints = {
@UniqueConstraint(columnNames = {"OWNER", "RESOURCE_SERVER_ID", "RESOURCE_ID", "SCOPE_ID"}) @UniqueConstraint(columnNames = {"OWNER", "RESOURCE_SERVER_ID", "RESOURCE_ID", "SCOPE_ID"})
}) })
@NamedQueries( @NamedQueries(

View file

@ -17,8 +17,8 @@
--> -->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd"> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.2.xsd">
<changeSet author="psilva@redhat.com" id="authz-3.3.0.CR1"> <changeSet author="psilva@redhat.com" id="authz-4.0.0.CR1">
<createTable tableName="RESOURCE_SERVER_PERMISSION_TICKET"> <createTable tableName="RESOURCE_SERVER_PERM_TICKET">
<column name="ID" type="VARCHAR(36)"> <column name="ID" type="VARCHAR(36)">
<constraints nullable="false"/> <constraints nullable="false"/>
</column> </column>
@ -45,11 +45,11 @@
</column> </column>
</createTable> </createTable>
<addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_FAPMT" tableName="RESOURCE_SERVER_PERMISSION_TICKET"/> <addPrimaryKey columnNames="ID" constraintName="CONSTRAINT_FAPMT" tableName="RESOURCE_SERVER_PERM_TICKET"/>
<addForeignKeyConstraint baseColumnNames="RESOURCE_SERVER_ID" baseTableName="RESOURCE_SERVER_PERMISSION_TICKET" constraintName="FK_FRSRHO213XCX4WNKOG82SSPMT" referencedColumnNames="ID" referencedTableName="RESOURCE_SERVER"/> <addForeignKeyConstraint baseColumnNames="RESOURCE_SERVER_ID" baseTableName="RESOURCE_SERVER_PERM_TICKET" constraintName="FK_FRSRHO213XCX4WNKOG82SSPMT" referencedColumnNames="ID" referencedTableName="RESOURCE_SERVER"/>
<addForeignKeyConstraint baseColumnNames="RESOURCE_ID" baseTableName="RESOURCE_SERVER_PERMISSION_TICKET" constraintName="FK_FRSRHO213XCX4WNKOG83SSPMT" referencedColumnNames="ID" referencedTableName="RESOURCE_SERVER_RESOURCE"/> <addForeignKeyConstraint baseColumnNames="RESOURCE_ID" baseTableName="RESOURCE_SERVER_PERM_TICKET" constraintName="FK_FRSRHO213XCX4WNKOG83SSPMT" referencedColumnNames="ID" referencedTableName="RESOURCE_SERVER_RESOURCE"/>
<addForeignKeyConstraint baseColumnNames="SCOPE_ID" baseTableName="RESOURCE_SERVER_PERMISSION_TICKET" constraintName="FK_FRSRHO213XCX4WNKOG84SSPMT" referencedColumnNames="ID" referencedTableName="RESOURCE_SERVER_SCOPE"/> <addForeignKeyConstraint baseColumnNames="SCOPE_ID" baseTableName="RESOURCE_SERVER_PERM_TICKET" constraintName="FK_FRSRHO213XCX4WNKOG84SSPMT" referencedColumnNames="ID" referencedTableName="RESOURCE_SERVER_SCOPE"/>
<addUniqueConstraint columnNames="OWNER, REQUESTER, RESOURCE_SERVER_ID, RESOURCE_ID, SCOPE_ID" constraintName="UK_FRSR6T700S9V50BU18WS5PMT" tableName="RESOURCE_SERVER_PERMISSION_TICKET"/> <addUniqueConstraint columnNames="OWNER, REQUESTER, RESOURCE_SERVER_ID, RESOURCE_ID, SCOPE_ID" constraintName="UK_FRSR6T700S9V50BU18WS5PMT" tableName="RESOURCE_SERVER_PERM_TICKET"/>
<addColumn tableName="RESOURCE_SERVER_RESOURCE"> <addColumn tableName="RESOURCE_SERVER_RESOURCE">
<column name="OWNER_MANAGED_ACCESS" type="BOOLEAN" defaultValueBoolean="false"> <column name="OWNER_MANAGED_ACCESS" type="BOOLEAN" defaultValueBoolean="false">

View file

@ -28,6 +28,7 @@ import javax.servlet.Filter;
import javax.servlet.Servlet; import javax.servlet.Servlet;
import io.undertow.servlet.api.DeploymentInfo; import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.ErrorPage;
import io.undertow.servlet.api.FilterInfo; import io.undertow.servlet.api.FilterInfo;
import io.undertow.servlet.api.LoginConfig; import io.undertow.servlet.api.LoginConfig;
import io.undertow.servlet.api.SecurityConstraint; import io.undertow.servlet.api.SecurityConstraint;
@ -183,9 +184,19 @@ class SimpleWebXmlParser {
cfg.setName(cookieName); cfg.setName(cookieName);
di.setServletSessionConfig(cfg); di.setServletSessionConfig(cfg);
} }
// ERROR PAGES
List<ElementWrapper> errorPages = document.getElementsByTagName("error-page");
for (ElementWrapper errorPage : errorPages) {
int errorCode = Integer.parseInt(errorPage.getElementByTagName("error-code").getText());
String location = errorPage.getElementByTagName("location").getText();
di.addErrorPage(new ErrorPage(location, errorCode));
}
} catch (ClassNotFoundException cnfe) { } catch (ClassNotFoundException cnfe) {
throw new RuntimeException(cnfe); throw new RuntimeException(cnfe);
} catch (NullPointerException npe) {
throw new RuntimeException("Error parsing web.xml of " + di.getDeploymentName(), npe);
} }
} }

View file

@ -14,9 +14,8 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>jboss-servlet-api_3.0_spec</artifactId>
<version>3.1.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>

View file

@ -23,22 +23,34 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import org.keycloak.adapters.spi.AuthenticationError;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/ */
public class ErrorServlet extends HttpServlet { public class ErrorServlet extends HttpServlet {
public static AuthenticationError authError;
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
authError = (AuthenticationError)req.getAttribute(AuthenticationError.class.getName());
Integer statusCode = (Integer) req.getAttribute("javax.servlet.error.status_code");
resp.setContentType("text/html"); resp.setContentType("text/html");
PrintWriter pw = resp.getWriter(); PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", "Error Page"); pw.printf("<html><head><title>%s</title></head><body>", "Error Page");
pw.print("<h1>There was an error</h1></body></html>"); pw.print("<h1>There was an error</h1>");
if (statusCode != null)
pw.print("<br/>HTTP status code: " + statusCode);
if (authError != null)
pw.print("<br/>Error info: " + authError.toString());
pw.print("</body></html>");
pw.flush(); pw.flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
} }
} }

View file

@ -31,10 +31,19 @@ public class MultiTenantResolver implements KeycloakConfigResolver {
@Override @Override
public KeycloakDeployment resolve(HttpFacade.Request request) { public KeycloakDeployment resolve(HttpFacade.Request request) {
String realm = request.getQueryParamValue("realm");
// FIXME doesn't work - need to load resources from WEB-INF String path = request.getURI();
InputStream is = getClass().getResourceAsStream("/" + realm + "-keycloak.json"); int multitenantIndex = path.indexOf("multi-tenant/");
if (multitenantIndex == -1) {
throw new IllegalStateException("Not able to resolve realm from the request path!");
}
String realm = path.substring(path.indexOf("multi-tenant/")).split("/")[1];
if (realm.contains("?")) {
realm = realm.split("\\?")[0];
}
InputStream is = getClass().getResourceAsStream("/adapter-test/multi-tenant/WEB-INF/" + realm + "-keycloak.json");
if (is == null) { if (is == null) {
throw new IllegalStateException("Not able to find the file /" + realm + "-keycloak.json"); throw new IllegalStateException("Not able to find the file /" + realm + "-keycloak.json");

View file

@ -33,6 +33,18 @@ public class MultiTenantServlet extends HttpServlet {
@Override @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String realm = req.getPathInfo().split("/")[1];
if (realm.contains("?")) {
realm = realm.split("\\?")[0];
}
if (req.getPathInfo() != null && req.getPathInfo().contains("logout")) {
req.logout();
resp.sendRedirect(req.getContextPath() + "/" + realm);
return;
}
resp.setContentType("text/html"); resp.setContentType("text/html");
PrintWriter pw = resp.getWriter(); PrintWriter pw = resp.getWriter();
KeycloakSecurityContext context = (KeycloakSecurityContext)req.getAttribute(KeycloakSecurityContext.class.getName()); KeycloakSecurityContext context = (KeycloakSecurityContext)req.getAttribute(KeycloakSecurityContext.class.getName());

View file

@ -0,0 +1,43 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter.page;
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
import java.net.URL;
public class CustomerCookiePortal extends AbstractPageWithInjectedUrl {
public static final String DEPLOYMENT_NAME = "customer-cookie-portal";
@ArquillianResource
@OperateOnDeployment(DEPLOYMENT_NAME)
private URL url;
@Override
public URL getInjectedUrl() {
return url;
}
public String logoutURL() {
return url + "/logout";
}
}

View file

@ -39,5 +39,9 @@ public class CustomerPortal extends AbstractPageWithInjectedUrl {
public URL getInjectedUrl() { public URL getInjectedUrl() {
return url; return url;
} }
public String logout() {
return url + "/logout";
}
} }

View file

@ -19,6 +19,7 @@ package org.keycloak.testsuite.adapter.page;
import org.jboss.arquillian.container.test.api.OperateOnDeployment; import org.jboss.arquillian.container.test.api.OperateOnDeployment;
import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.page.AbstractPageWithInjectedUrl;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -28,9 +29,9 @@ import java.net.URL;
* *
* @author vramik * @author vramik
*/ */
public class InputPortalNoAccessToken extends SAMLServlet { public class InputPortalNoAccessToken extends AbstractPageWithInjectedUrl {
public static final String DEPLOYMENT_NAME = "input-portal-no-access-token"; public static final String DEPLOYMENT_NAME = "no-access-token";
@ArquillianResource @ArquillianResource
@OperateOnDeployment(DEPLOYMENT_NAME) @OperateOnDeployment(DEPLOYMENT_NAME)

View file

@ -67,7 +67,7 @@ public class AuthServerTestEnricher {
@Inject @Inject
private Event<StopContainer> stopContainerEvent; private Event<StopContainer> stopContainerEvent;
private static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow"; public static final String AUTH_SERVER_CONTAINER_DEFAULT = "auth-server-undertow";
private static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container"; private static final String AUTH_SERVER_CONTAINER_PROPERTY = "auth.server.container";
public static final String AUTH_SERVER_CONTAINER = System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT); public static final String AUTH_SERVER_CONTAINER = System.getProperty(AUTH_SERVER_CONTAINER_PROPERTY, AUTH_SERVER_CONTAINER_DEFAULT);

View file

@ -56,6 +56,8 @@ import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isTomcatAp
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isWLSAppServer; import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isWLSAppServer;
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isWASAppServer; import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isWASAppServer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot; import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
import static org.keycloak.testsuite.util.IOUtil.appendChildInDocument; import static org.keycloak.testsuite.util.IOUtil.appendChildInDocument;
import static org.keycloak.testsuite.util.IOUtil.documentToString; import static org.keycloak.testsuite.util.IOUtil.documentToString;
import static org.keycloak.testsuite.util.IOUtil.getElementTextContent; import static org.keycloak.testsuite.util.IOUtil.getElementTextContent;
@ -186,8 +188,9 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
AdapterConfig adapterConfig = loadJson(archive.get(adapterConfigPath) AdapterConfig adapterConfig = loadJson(archive.get(adapterConfigPath)
.getAsset().openStream(), AdapterConfig.class); .getAsset().openStream(), AdapterConfig.class);
log.info(" setting " + (relative ? "" : "non-") + "relative auth-server-url"); // TODO find out if this is necessary
if (relative) { if (relative && !AUTH_SERVER_CONTAINER.equals(AUTH_SERVER_CONTAINER_DEFAULT)) {
log.info(" setting relative auth-server-url");
adapterConfig.setAuthServerUrl("/auth"); adapterConfig.setAuthServerUrl("/auth");
// ac.setRealmKey(null); // TODO verify if realm key is required for relative scneario // ac.setRealmKey(null); // TODO verify if realm key is required for relative scneario
} else { } else {

View file

@ -37,6 +37,11 @@ import static org.keycloak.testsuite.util.IOUtil.loadRealm;
public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest { public abstract class AbstractServletsAdapterTest extends AbstractAdapterTest {
protected static WebArchive servletDeploymentMultiTenant(String name, Class... servletClasses) {
WebArchive servletDeployment = servletDeployment(name, null, servletClasses);
return servletDeployment;
}
protected static WebArchive servletDeployment(String name, Class... servletClasses) { protected static WebArchive servletDeployment(String name, Class... servletClasses) {
return servletDeployment(name, "keycloak.json", servletClasses); return servletDeployment(name, "keycloak.json", servletClasses);
} }

View file

@ -1,23 +1,42 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter.servlet; package org.keycloak.testsuite.adapter.servlet;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.keycloak.testsuite.arquillian.annotation.UseServletFilter; import org.keycloak.testsuite.arquillian.annotation.UseServletFilter;
/**
* Created by zschwarz on 9/14/16.
*/
@UseServletFilter(filterName = "oidc-filter", filterClass = "org.keycloak.adapters.servlet.KeycloakOIDCFilter", @UseServletFilter(filterName = "oidc-filter", filterClass = "org.keycloak.adapters.servlet.KeycloakOIDCFilter",
filterDependency = "org.keycloak:keycloak-servlet-filter-adapter", skipPattern = "/error.html") filterDependency = "org.keycloak:keycloak-servlet-filter-adapter", skipPattern = "/error.html")
public abstract class AbstractDemoFilterServletAdapterTest extends AbstractDemoServletsAdapterTest { public abstract class AbstractDemoFilterServletAdapterTest extends AbstractDemoServletsAdapterTest {
@Test
@Override
@Ignore
public void testNullBearerTokenCustomErrorPage() {
//can't test because of the way filter works
}
@Test @Test
@Override @Override
@Ignore @Ignore
public void testAuthenticated() { public void testAuthenticated() {
//Don't need to test this because HttpServletRequest.authenticate doesn't make sense with filter implementation
} }
@Test @Test
@ -40,4 +59,25 @@ public abstract class AbstractDemoFilterServletAdapterTest extends AbstractDemoS
public void testOIDCUiLocalesParamForwarding() { public void testOIDCUiLocalesParamForwarding() {
} }
@Test
@Override
@Ignore
public void testTokenInCookieSSO() {
}
@Test
@Override
@Ignore
public void testInvalidTokenCookie() {
}
@Test
@Override
@Ignore
public void testTokenInCookieRefresh() {
}
} }

View file

@ -39,12 +39,13 @@ import org.jboss.arquillian.graphene.page.Page;
import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.openqa.selenium.Cookie;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.adapters.OIDCAuthenticationError;
import org.keycloak.common.Version; import org.keycloak.common.Version;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
import org.keycloak.constants.AdapterConstants; import org.keycloak.constants.AdapterConstants;
@ -65,6 +66,7 @@ import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter; import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
import org.keycloak.testsuite.adapter.page.BasicAuth; import org.keycloak.testsuite.adapter.page.BasicAuth;
import org.keycloak.testsuite.adapter.page.ClientSecretJwtSecurePortal; import org.keycloak.testsuite.adapter.page.ClientSecretJwtSecurePortal;
import org.keycloak.testsuite.adapter.page.CustomerCookiePortal;
import org.keycloak.testsuite.adapter.page.CustomerDb; import org.keycloak.testsuite.adapter.page.CustomerDb;
import org.keycloak.testsuite.adapter.page.CustomerDbErrorPage; import org.keycloak.testsuite.adapter.page.CustomerDbErrorPage;
import org.keycloak.testsuite.adapter.page.CustomerPortal; import org.keycloak.testsuite.adapter.page.CustomerPortal;
@ -101,6 +103,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO; import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO;
@ -148,7 +151,9 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
private Config configPage; private Config configPage;
@Page @Page
private ClientSecretJwtSecurePortal clientSecretJwtSecurePortal; private ClientSecretJwtSecurePortal clientSecretJwtSecurePortal;
@Page
private CustomerCookiePortal customerCookiePortal;
@Rule @Rule
public AssertEvents assertEvents = new AssertEvents(this); public AssertEvents assertEvents = new AssertEvents(this);
@ -157,6 +162,11 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class); return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class);
} }
@Deployment(name = CustomerCookiePortal.DEPLOYMENT_NAME)
protected static WebArchive customerCookiePortal() {
return servletDeployment(CustomerCookiePortal.DEPLOYMENT_NAME, CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class);
}
@Deployment(name = CustomerPortalNoConf.DEPLOYMENT_NAME) @Deployment(name = CustomerPortalNoConf.DEPLOYMENT_NAME)
protected static WebArchive customerPortalNoConf() { protected static WebArchive customerPortalNoConf() {
return servletDeployment(CustomerPortalNoConf.DEPLOYMENT_NAME, CustomerServletNoConf.class, ErrorServlet.class); return servletDeployment(CustomerPortalNoConf.DEPLOYMENT_NAME, CustomerServletNoConf.class, ErrorServlet.class);
@ -233,6 +243,127 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
driver.manage().deleteAllCookies(); driver.manage().deleteAllCookies();
} }
//KEYCLOAK-702
@Test
public void testTokenInCookieSSO() {
// Login
String tokenCookie = loginToCustomerCookiePortal();
// SSO to second app
customerPortal.navigateTo();
assertLogged();
// return to customer-cookie-portal and assert still same cookie (accessToken didn't expire)
customerCookiePortal.navigateTo();
assertLogged();
String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
assertEquals(tokenCookie, tokenCookie2);
// Logout with httpServletRequest
logoutFromCustomerCookiePortal();
// Also should be logged-out from the second app
customerPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
}
//KEYCLOAK-702
@Test
public void testTokenInCookieRefresh() {
// Set token timeout 3 sec
RealmRepresentation demo = adminClient.realm("demo").toRepresentation();
int originalTokenTimeout = demo.getAccessCodeLifespan();
demo.setAccessTokenLifespan(3);
adminClient.realm("demo").update(demo);
try {
// login to customer-cookie-portal
String tokenCookie1 = loginToCustomerCookiePortal();
// Simulate waiting 4 seconds
setTimeOffset(4);
// assert cookie was refreshed
customerCookiePortal.navigateTo();
assertCurrentUrlEquals(customerCookiePortal);
assertLogged();
String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
assertNotEquals(tokenCookie1, tokenCookie2);
// login to 2nd app and logout from it
customerPortal.navigateTo();
assertCurrentUrlEquals(customerPortal);
assertLogged();
driver.navigate().to(customerCookiePortal.logoutURL());
assertTrue(driver.getPageSource().contains("servlet logout ok"));
customerPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
// Simulate another 4 seconds
setTimeOffset(8);
// assert not logged in customer-cookie-portal
customerCookiePortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
} finally {
// Set token timeout 3 sec
demo.setAccessTokenLifespan(originalTokenTimeout);
adminClient.realm("demo").update(demo);
resetTimeOffset();
}
}
//KEYCLOAK-702
@Test
public void testInvalidTokenCookie() {
// Login
String tokenCookie = loginToCustomerCookiePortal();
String changedTokenCookie = tokenCookie.replace("a", "b");
// change cookie to invalid value
driver.manage().addCookie(new Cookie(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE, changedTokenCookie, "/customer-cookie-portal"));
// visit page and assert re-logged and cookie was refreshed
customerCookiePortal.navigateTo();
assertCurrentUrlEquals(customerCookiePortal);
String currentCookie = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
assertNotEquals(currentCookie, tokenCookie);
assertNotEquals(currentCookie, changedTokenCookie);
// logout
logoutFromCustomerCookiePortal();
}
// login to customer-cookie-portal and return the KEYCLOAK_ADAPTER_STATE cookie established on adapter
private String loginToCustomerCookiePortal() {
customerCookiePortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
testRealmLoginPage.form().login("bburke@redhat.com", "password");
assertCurrentUrlEquals(customerCookiePortal);
assertLogged();
// Assert no JSESSIONID cookie
Assert.assertNull(driver.manage().getCookieNamed("JSESSIONID"));
return driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
}
private void logoutFromCustomerCookiePortal() {
String logout = customerCookiePortal.logoutURL();
driver.navigate().to(logout);
assertTrue(driver.getPageSource().contains("servlet logout ok"));
assertNull(driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE));
customerCookiePortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
}
private void assertLogged() {
String pageSource = driver.getPageSource();
Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
}
@Test @Test
public void testSavedPostRequest() throws InterruptedException { public void testSavedPostRequest() throws InterruptedException {
// 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
@ -437,6 +568,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
driver.navigate().to(logoutUri); driver.navigate().to(logoutUri);
} }
//KEYCLOAK-518
@Test @Test
public void testNullBearerToken() { public void testNullBearerToken() {
Client client = ClientBuilder.newClient(); Client client = ClientBuilder.newClient();
@ -450,41 +582,39 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
client.close(); client.close();
} }
//KEYCLOAK-1368
@Test @Test
@Ignore
public void testNullBearerTokenCustomErrorPage() { public void testNullBearerTokenCustomErrorPage() {
ErrorServlet.authError = null;
Client client = ClientBuilder.newClient(); Client client = ClientBuilder.newClient();
WebTarget target = client.target(customerDbErrorPage.toString()); WebTarget target = client.target(customerDbErrorPage.toString());
Response response = target.request().get(); Response response = target.request().get();
// TODO: follow redirects automatically if possible assertEquals(401, response.getStatus());
if (response.getStatus() == 302) {
String location = response.getHeaderString(HttpHeaders.LOCATION);
response.close();
response = client.target(location).request().get();
}
assertEquals(200, response.getStatus());
String errorPageResponse = response.readEntity(String.class); String errorPageResponse = response.readEntity(String.class);
assertTrue(errorPageResponse.contains("Error Page")); assertTrue(errorPageResponse.contains("Error Page"));
response.close(); response.close();
Assert.assertNotNull(ErrorServlet.authError);
OIDCAuthenticationError error = (OIDCAuthenticationError) ErrorServlet.authError;
Assert.assertEquals(OIDCAuthenticationError.Reason.NO_BEARER_TOKEN, error.getReason());
ErrorServlet.authError = null;
response = target.request().header(HttpHeaders.AUTHORIZATION, "Bearer null").get(); response = target.request().header(HttpHeaders.AUTHORIZATION, "Bearer null").get();
// TODO: follow redirects automatically if possible
if (response.getStatus() == 302) { assertEquals(401, response.getStatus());
String location = response.getHeaderString(HttpHeaders.LOCATION);
response.close();
response = client.target(location).request().get();
}
assertEquals(200, response.getStatus());
errorPageResponse = response.readEntity(String.class); errorPageResponse = response.readEntity(String.class);
assertTrue(errorPageResponse.contains("Error Page")); assertTrue(errorPageResponse.contains("Error Page"));
response.close(); response.close();
Assert.assertNotNull(ErrorServlet.authError);
error = (OIDCAuthenticationError) ErrorServlet.authError;
Assert.assertEquals(OIDCAuthenticationError.Reason.INVALID_TOKEN, error.getReason());
client.close(); client.close();
} }
//KEYCLOAK-518
@Test @Test
@Ignore
public void testBadUser() { public void testBadUser() {
Client client = ClientBuilder.newClient(); Client client = ClientBuilder.newClient();
URI uri = OIDCLoginProtocolService.tokenUrl(authServerPage.createUriBuilder()).build("demo"); URI uri = OIDCLoginProtocolService.tokenUrl(authServerPage.createUriBuilder()).build("demo");
@ -1016,7 +1146,6 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
//KEYCLOAK-4765 //KEYCLOAK-4765
@Test @Test
@Ignore
public void testCallURLWithAccessToken() { public void testCallURLWithAccessToken() {
// 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
String applicationURL = inputPortalNoAccessToken.getInjectedUrl().toString() + "?access_token=invalid_token"; String applicationURL = inputPortalNoAccessToken.getInjectedUrl().toString() + "?access_token=invalid_token";
@ -1026,6 +1155,7 @@ public abstract class AbstractDemoServletsAdapterTest extends AbstractServletsAd
Assert.assertEquals(applicationURL, driver.getCurrentUrl()); Assert.assertEquals(applicationURL, driver.getCurrentUrl());
System.out.println(driver.getPageSource()); System.out.println(driver.getPageSource());
inputPortalNoAccessToken.execute("hello"); inputPortalNoAccessToken.execute("hello");
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
} }
@Test @Test

View file

@ -0,0 +1,31 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter.servlet;
import org.junit.Ignore;
import org.junit.Test;
public abstract class AbstractSessionFilterServletAdapterTest extends AbstractSessionServletAdapterTest {
@Test
@Override
@Ignore
public void testAccountManagementSessionsLogout() {
//Can't test this because backchannel logout for filter does not invalidate the session
}
}

View file

@ -76,6 +76,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
@SecondBrowser @SecondBrowser
protected WebDriver driver2; protected WebDriver driver2;
//KEYCLOAK-732
@Test @Test
public void testSingleSessionInvalidated() { public void testSingleSessionInvalidated() {
@ -116,6 +117,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
} }
//KEYCLOAK-741
@Test @Test
public void testSessionInvalidatedAfterFailedRefresh() { public void testSessionInvalidatedAfterFailedRefresh() {
RealmRepresentation testRealmRep = testRealmResource().toRepresentation(); RealmRepresentation testRealmRep = testRealmResource().toRepresentation();
@ -152,6 +154,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
testRealmResource().update(testRealmRep); testRealmResource().update(testRealmRep);
} }
//KEYCLOAK-942
@Test @Test
public void testAdminApplicationLogout() { public void testAdminApplicationLogout() {
// login as bburke // login as bburke
@ -171,6 +174,7 @@ public abstract class AbstractSessionServletAdapterTest extends AbstractServlets
driver.navigate().to(logoutUri); driver.navigate().to(logoutUri);
} }
//KEYCLOAK-1216
@Test @Test
public void testAccountManagementSessionsLogout() { public void testAccountManagementSessionsLogout() {
// login as bburke // login as bburke

View file

@ -0,0 +1,146 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter.undertow.servlet;
import java.util.List;
import javax.ws.rs.core.UriBuilder;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
import org.keycloak.testsuite.adapter.servlet.ErrorServlet;
import org.keycloak.testsuite.adapter.servlet.MultiTenantResolver;
import org.keycloak.testsuite.adapter.servlet.MultiTenantServlet;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
import org.keycloak.testsuite.util.URLAssert;
import org.keycloak.testsuite.util.WaitUtils;
/**
* note: migrated from old testsuite
*
* @author Juraci Paixão Kröhling <juraci at kroehling.de>
*/
@AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class MultiTenancyTest extends AbstractServletsAdapterTest {
@Override
public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
testRealms.add(loadRealm("/adapter-test/tenant1-realm.json"));
testRealms.add(loadRealm("/adapter-test/tenant2-realm.json"));
}
@Override
protected boolean isImportAfterEachMethod() {
return false;
}
@Deployment(name = "multi-tenant")
protected static WebArchive multiTenant() {
return servletDeploymentMultiTenant("multi-tenant", MultiTenantServlet.class, ErrorServlet.class, MultiTenantResolver.class);
}
@After
public void afterTest() {
driver.manage().deleteAllCookies();
}
/**
* Simplest scenario: one user, one realm. The user is not logged in at
* any other realm
*/
@Test
public void testTenantsLoggingOut() {
doTenantRequests("tenant1", true);
doTenantRequests("tenant2", true);
}
/**
* This tests the adapter's ability to deal with multiple sessions
* from the same user, one for each realm. It should not mixup and return
* a session from tenant1 to tenant2
*/
@Test
public void testTenantsWithoutLoggingOut() {
doTenantRequests("tenant1", true);
doTenantRequests("tenant2", true);
doTenantRequests("tenant1", false);
doTenantRequests("tenant2", true);
}
/**
* This test simulates an user that is not logged in yet, and tries to login
* into tenant1 using an account from tenant2.
* On this scenario, the user should be shown the login page again.
*/
@Test
public void testUnauthorizedAccessNotLoggedIn() {
String keycloakServerBaseUrl = authServerPage.toString();
driver.navigate().to(authServerContextRootPage + "/multi-tenant/tenant1");
WaitUtils.waitForPageToLoad();
URLAssert.assertCurrentUrlStartsWith(keycloakServerBaseUrl);
String currentUrl = driver.getCurrentUrl();
String toString = testRealmLoginPage.toString();
testRealmLoginPage.form().login("user-tenant2", "user-tenant2");
URLAssert.assertCurrentUrlStartsWith(keycloakServerBaseUrl);
}
/**
* This test simulates an user which is already logged in into tenant1
* and tries to access a resource on tenant2.
* On this scenario, the user should be shown the login page again.
*/
@Test
public void testUnauthorizedAccessLoggedIn() {
doTenantRequests("tenant1", false);
driver.navigate().to(authServerContextRootPage + "/multi-tenant/tenant2");
URLAssert.assertCurrentUrlStartsWith(authServerPage.toString());
}
private void doTenantRequests(String tenant, boolean logout) {
String tenantLoginUrl = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri(authServerPage.getAuthRoot())).build(tenant).toString();
String tenantUrl = authServerContextRootPage + "/multi-tenant/" + tenant;
driver.navigate().to(tenantUrl);
URLAssert.assertCurrentUrlStartsWith(tenantLoginUrl);
testRealmLoginPage.form().login("bburke@redhat.com", "password");
log.debug("Current url: " + driver.getCurrentUrl());
URLAssert.assertCurrentUrlStartsWith(tenantUrl);
String pageSource = driver.getPageSource();
log.debug(pageSource);
Assert.assertTrue(pageSource.contains("Username: bburke@redhat.com"));
Assert.assertTrue(pageSource.contains("Realm: " + tenant));
if (logout) {
driver.navigate().to(authServerContextRootPage + "/multi-tenant/" + tenant + "/logout");
Assert.assertFalse(driver.getPageSource().contains("Username: bburke@redhat.com"));
Assert.assertTrue(driver.getCurrentUrl().startsWith(tenantLoginUrl));
}
log.debug("---------------------------------------------------------------------------------------");
}
}

View file

@ -20,11 +20,13 @@ import org.junit.Test;
import org.keycloak.testsuite.adapter.servlet.AbstractBrokerLinkAndTokenExchangeTest; import org.keycloak.testsuite.adapter.servlet.AbstractBrokerLinkAndTokenExchangeTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
/** /**
* *
* @author <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a> * @author <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowBrokerLinkAndTokenExchangeTest extends AbstractBrokerLinkAndTokenExchangeTest { public class UndertowBrokerLinkAndTokenExchangeTest extends AbstractBrokerLinkAndTokenExchangeTest {
//@Test //@Test

View file

@ -20,11 +20,13 @@ import org.junit.Test;
import org.keycloak.testsuite.adapter.servlet.AbstractClientInitiatedAccountLinkTest; import org.keycloak.testsuite.adapter.servlet.AbstractClientInitiatedAccountLinkTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
/** /**
* *
* @author <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a> * @author <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowClientInitiatedAccountLinkTest extends AbstractClientInitiatedAccountLinkTest { public class UndertowClientInitiatedAccountLinkTest extends AbstractClientInitiatedAccountLinkTest {
//@Test //@Test

View file

@ -20,11 +20,11 @@ package org.keycloak.testsuite.adapter.undertow.servlet;
import org.keycloak.testsuite.adapter.servlet.AbstractDemoFilterServletAdapterTest; import org.keycloak.testsuite.adapter.servlet.AbstractDemoFilterServletAdapterTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import org.junit.Ignore; import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowDemoFilterServletAdapterTest extends AbstractDemoFilterServletAdapterTest { public class UndertowDemoFilterServletAdapterTest extends AbstractDemoFilterServletAdapterTest {
} }

View file

@ -17,14 +17,21 @@
package org.keycloak.testsuite.adapter.undertow.servlet; package org.keycloak.testsuite.adapter.undertow.servlet;
import org.junit.Test;
import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest; import org.keycloak.testsuite.adapter.servlet.AbstractDemoServletsAdapterTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import org.junit.Ignore; import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowDemoServletsAdapterTest extends AbstractDemoServletsAdapterTest { public class UndertowDemoServletsAdapterTest extends AbstractDemoServletsAdapterTest {
@Test
@Override
public void testLoginEncodedRedirectUri() {
super.testLoginEncodedRedirectUri();
}
} }

View file

@ -20,9 +20,11 @@ package org.keycloak.testsuite.adapter.undertow.servlet;
import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest; import org.keycloak.testsuite.adapter.servlet.AbstractOIDCPublicKeyRotationAdapterTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowOIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest { public class UndertowOIDCPublicKeyRotationAdapterTest extends AbstractOIDCPublicKeyRotationAdapterTest {
} }

View file

@ -20,9 +20,11 @@ package org.keycloak.testsuite.adapter.undertow.servlet;
import org.keycloak.testsuite.adapter.servlet.AbstractOfflineServletsAdapterTest; import org.keycloak.testsuite.adapter.servlet.AbstractOfflineServletsAdapterTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowOfflineServletsAdapterTest extends AbstractOfflineServletsAdapterTest { public class UndertowOfflineServletsAdapterTest extends AbstractOfflineServletsAdapterTest {
} }

View file

@ -0,0 +1,149 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter.undertow.servlet;
import java.util.List;
import java.util.Map;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.adapter.AbstractServletsAdapterTest;
import org.keycloak.testsuite.adapter.filter.AdapterActionsFilter;
import org.keycloak.testsuite.adapter.page.CustomerDb;
import org.keycloak.testsuite.adapter.page.CustomerPortal;
import org.keycloak.testsuite.adapter.page.ProductPortal;
import org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet;
import org.keycloak.testsuite.adapter.servlet.CustomerServlet;
import org.keycloak.testsuite.adapter.servlet.ErrorServlet;
import org.keycloak.testsuite.adapter.servlet.ProductServlet;
import org.keycloak.testsuite.adapter.servlet.ServletTestUtils;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
import static org.keycloak.testsuite.auth.page.AuthRealm.DEMO;
import static org.keycloak.testsuite.util.IOUtil.loadRealm;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
/**
* Also tests relative URIs in the adapter and valid redirect uris.
* Also tests adapters not configured with public key
*
* note: migrated from old testsuite
*
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
*/
@AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowRelaviteUriAdapterTest extends AbstractServletsAdapterTest {
@Page
private CustomerPortal customerPortal;
@Page
private ProductPortal productPortal;
@Override
public void addAdapterTestRealms(List<RealmRepresentation> testRealms) {
testRealms.add(loadRealm("/adapter-test/demorealm-relative.json"));
}
@Deployment(name = CustomerPortal.DEPLOYMENT_NAME)
protected static WebArchive customerPortal() {
return servletDeployment(CustomerPortal.DEPLOYMENT_NAME, "keycloak-relative.json", CustomerServlet.class, ErrorServlet.class, ServletTestUtils.class);
}
@Deployment(name = CustomerDb.DEPLOYMENT_NAME)
protected static WebArchive customerDb() {
return servletDeployment(CustomerDb.DEPLOYMENT_NAME, "keycloak-relative.json", AdapterActionsFilter.class, CustomerDatabaseServlet.class);
}
@Deployment(name = ProductPortal.DEPLOYMENT_NAME)
protected static WebArchive productPortal() {
return servletDeployment(ProductPortal.DEPLOYMENT_NAME, "keycloak-relative.json", ProductServlet.class);
}
@Test
public void testLoginSSOAndLogout() {
// test login to customer-portal which does a bearer request to customer-db
customerPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
testRealmLoginPage.form().login("bburke@redhat.com", "password");
assertCurrentUrlEquals(customerPortal);
String pageSource = driver.getPageSource();
Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
// test SSO
productPortal.navigateTo();
assertCurrentUrlEquals(productPortal);
pageSource = driver.getPageSource();
Assert.assertTrue(pageSource.contains("iPhone") && pageSource.contains("iPad"));
// View stats
List<Map<String, String>> stats = adminClient.realm(DEMO).getClientSessionStats();
Map<String, String> customerPortalStats = null;
Map<String, String> productPortalStats = null;
for (Map<String, String> s : stats) {
switch (s.get("clientId")) {
case "customer-portal":
customerPortalStats = s;
break;
case "product-portal":
productPortalStats = s;
break;
}
}
Assert.assertEquals(1, Integer.parseInt(customerPortalStats.get("active")));
Assert.assertEquals(1, Integer.parseInt(productPortalStats.get("active")));
// test logout
String logoutUri = OIDCLoginProtocolService.logoutUrl(authServerPage.createUriBuilder())
.queryParam(OAuth2Constants.REDIRECT_URI, customerPortal.toString()).build("demo").toString();
driver.navigate().to(logoutUri);
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
productPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
customerPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
}
@Test
public void testServletRequestLogout() {
customerPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
testRealmLoginPage.form().login("bburke@redhat.com", "password");
assertCurrentUrlEquals(customerPortal);
Assert.assertTrue(driver.getPageSource().contains("Bill Burke"));
productPortal.navigateTo();
assertCurrentUrlEquals(productPortal);
Assert.assertTrue(driver.getPageSource().contains("iPhone"));
// test logout
driver.navigate().to(customerPortal.logout());
Assert.assertTrue(driver.getPageSource().contains("servlet logout ok"));
customerPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
productPortal.navigateTo();
assertCurrentUrlStartsWithLoginUrlOf(testRealmPage);
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright 2018 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter.undertow.servlet;
import org.keycloak.testsuite.adapter.servlet.AbstractSessionFilterServletAdapterTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
@AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowSessionFilterServletAdapterTest extends AbstractSessionFilterServletAdapterTest {
}

View file

@ -20,9 +20,11 @@ package org.keycloak.testsuite.adapter.undertow.servlet;
import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest; import org.keycloak.testsuite.adapter.servlet.AbstractSessionServletAdapterTest;
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer; import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UndertowSessionServletAdapterTest extends AbstractSessionServletAdapterTest { public class UndertowSessionServletAdapterTest extends AbstractSessionServletAdapterTest {
} }

View file

@ -52,6 +52,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.AUTH_SERVER_CONTAINER_DEFAULT;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLoginUrlOf;
@ -59,7 +60,7 @@ import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWithLo
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
@AppServerContainer("auth-server-undertow") @AppServerContainer(AUTH_SERVER_CONTAINER_DEFAULT)
public class UserStorageConsentTest extends AbstractServletsAdapterTest { public class UserStorageConsentTest extends AbstractServletsAdapterTest {
@Page @Page

View file

@ -0,0 +1,20 @@
<!--
~ Copyright 2018 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<Context path="/customer-portal">
<Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
</Context>

View file

@ -0,0 +1,46 @@
<?xml version="1.0"?>
<!--
~ Copyright 2018 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="securityHandler">
<Set name="authenticator">
<New class="org.keycloak.adapters.jetty.KeycloakJettyAuthenticator">
<!--
<Set name="adapterConfig">
<New class="org.keycloak.representations.adapters.config.AdapterConfig">
<Set name="realm">tomcat</Set>
<Set name="resource">customer-portal</Set>
<Set name="authServerUrl">http://localhost:8180/auth</Set>
<Set name="sslRequired">external</Set>
<Set name="credentials">
<Map>
<Entry>
<Item>secret</Item>
<Item>password</Item>
</Entry>
</Map>
</Set>
<Set name="realmKey">MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB</Set>
</New>
</Set>
-->
</New>
</Set>
</Get>
</Configure>

View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2018 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<module-name>customer-cookie-portal</module-name>
<servlet>
<servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Error Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Error Servlet</servlet-name>
<url-pattern>/error.html</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Users</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Errors</web-resource-name>
<url-pattern>/error.html</url-pattern>
</web-resource-collection>
</security-constraint>
<login-config>
<auth-method>KEYCLOAK</auth-method>
<realm-name>demo</realm-name>
</login-config>
<security-role>
<role-name>user</role-name>
</security-role>
</web-app>

View file

@ -32,6 +32,23 @@
<servlet-class>org.keycloak.testsuite.adapter.servlet.ErrorServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.ErrorServlet</servlet-class>
</servlet> </servlet>
<error-page>
<error-code>400</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>401</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>403</error-code>
<location>/error.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error.html</location>
</error-page>
<servlet-mapping> <servlet-mapping>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<url-pattern>/*</url-pattern> <url-pattern>/*</url-pattern>

View file

@ -0,0 +1,107 @@
{
"realm": "demo",
"enabled": true,
"accessTokenLifespan": 3000,
"accessCodeLifespan": 10,
"accessCodeLifespanUserAction": 6000,
"sslRequired": "external",
"registrationAllowed": false,
"privateKey": "MIICXAIBAAKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQABAoGAfmO8gVhyBxdqlxmIuglbz8bcjQbhXJLR2EoS8ngTXmN1bo2L90M0mUKSdc7qF10LgETBzqL8jYlQIbt+e6TH8fcEpKCjUlyq0Mf/vVbfZSNaVycY13nTzo27iPyWQHK5NLuJzn1xvxxrUeXI6A2WFpGEBLbHjwpx5WQG9A+2scECQQDvdn9NE75HPTVPxBqsEd2z10TKkl9CZxu10Qby3iQQmWLEJ9LNmy3acvKrE3gMiYNWb6xHPKiIqOR1as7L24aTAkEAtyvQOlCvr5kAjVqrEKXalj0Tzewjweuxc0pskvArTI2Oo070h65GpoIKLc9jf+UA69cRtquwP93aZKtW06U8dQJAF2Y44ks/mK5+eyDqik3koCI08qaC8HYq2wVl7G2QkJ6sbAaILtcvD92ToOvyGyeE0flvmDZxMYlvaZnaQ0lcSQJBAKZU6umJi3/xeEbkJqMfeLclD27XGEFoPeNrmdx0q10Azp4NfJAY+Z8KRyQCR2BEG+oNitBOZ+YXF9KCpH3cdmECQHEigJhYg+ykOvr1aiZUMFT72HU0jnmQe2FVekuG+LJUt2Tm7GtMjTFoGpf0JwrVuZN39fOYAlo+nTixgeW7X8Y=",
"publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"requiredCredentials": [ "password" ],
"users" : [
{
"username" : "bburke@redhat.com",
"enabled": true,
"email" : "bburke@redhat.com",
"firstName": "Bill",
"lastName": "Burke",
"credentials" : [
{ "type" : "password",
"value" : "password" }
],
"realmRoles": [ "user" ],
"applicationRoles": {
"account": [ "manage-account" ]
}
}
],
"roles" : {
"realm" : [
{
"name": "user",
"description": "User privileges"
},
{
"name": "admin",
"description": "Administrator privileges"
}
]
},
"scopeMappings": [
{
"client": "third-party",
"roles": ["user"]
},
{
"client": "customer-portal",
"roles": ["user"]
},
{
"client": "product-portal",
"roles": ["user"]
}
],
"applications": [
{
"name": "customer-portal",
"enabled": true,
"adminUrl": "/customer-portal",
"baseUrl": "/customer-portal",
"redirectUris": [
"/customer-portal/*"
],
"secret": "password"
},
{
"name": "customer-portal-js",
"enabled": true,
"publicClient": true,
"baseUrl": "/customer-portal-js",
"redirectUris": [
"/customer-portal-js/*"
]
},
{
"name": "customer-portal-cli",
"enabled": true,
"publicClient": true,
"redirectUris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
]
},
{
"name": "product-portal",
"enabled": true,
"adminUrl": "/product-portal",
"baseUrl": "/product-portal",
"redirectUris": [
"/product-portal/*"
],
"secret": "password"
}
],
"oauthClients": [
{
"name": "third-party",
"enabled": true,
"redirectUris": [
"/oauth-client/*",
"/oauth-client-cdi/*"
],
"secret": "password"
}
]
}

View file

@ -141,7 +141,8 @@
"redirectUris": [ "redirectUris": [
"/customer-portal/*" "/customer-portal/*"
], ],
"secret": "password" "secret": "password",
"directAccessGrantsEnabled": true
}, },
{ {
"clientId": "customer-portal-subsystem", "clientId": "customer-portal-subsystem",

View file

@ -1,7 +1,7 @@
{ {
"realm" : "demo", "realm" : "demo",
"resource" : "input-portal", "resource" : "input-portal",
"auth-server-url" : "http://${my.host.name}:8180/auth", "auth-server-url" : "http://localhost:8180/auth",
"ssl-required" : "external", "ssl-required" : "external",
"min-time-between-jwks-requests": 120, "min-time-between-jwks-requests": 120,
"credentials" : { "credentials" : {

View file

@ -0,0 +1,20 @@
<!--
~ Copyright 2018 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<Context path="/multi-tenant">
<Valve className="org.keycloak.adapters.tomcat.KeycloakAuthenticatorValve"/>
</Context>

View file

@ -34,7 +34,7 @@
</context-param> </context-param>
<servlet-mapping> <servlet-mapping>
<servlet-name>Servlet</servlet-name> <servlet-name>MultiTenantServlet</servlet-name>
<url-pattern>/*</url-pattern> <url-pattern>/*</url-pattern>
</servlet-mapping> </servlet-mapping>
@ -50,6 +50,7 @@
<login-config> <login-config>
<auth-method>KEYCLOAK</auth-method> <auth-method>KEYCLOAK</auth-method>
<realm-name>not-important</realm-name>
</login-config> </login-config>
<security-role> <security-role>

View file

@ -1,10 +1,9 @@
{ {
"realm" : "demo", "realm" : "demo",
"resource" : "input-portal-no-access-token", "resource" : "no-access-token",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "http://${my.host.name}:8180/auth", "auth-server-url" : "http://localhost:8180/auth",
"ssl-required" : "external", "ssl-required" : "external",
"min-time-between-jwks-requests": 120,
"credentials" : { "credentials" : {
"secret": "password" "secret": "password"
}, },

View file

@ -21,7 +21,7 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"> version="3.0">
<module-name>input-portal-no-access-token</module-name> <module-name>no-access-token</module-name>
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
@ -42,15 +42,18 @@
<role-name>user</role-name> <role-name>user</role-name>
</auth-constraint> </auth-constraint>
</security-constraint> </security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>public</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
</security-constraint>
<login-config> <login-config>
<auth-method>KEYCLOAK</auth-method> <auth-method>KEYCLOAK</auth-method>
<realm-name>demo</realm-name> <realm-name>demo</realm-name>
</login-config> </login-config>
<security-role>
<role-name>admin</role-name>
</security-role>
<security-role> <security-role>
<role-name>user</role-name> <role-name>user</role-name>
</security-role> </security-role>

View file

@ -2,7 +2,7 @@
"realm" : "demo", "realm" : "demo",
"resource" : "session-portal", "resource" : "session-portal",
"realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", "realm-public-key" : "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
"auth-server-url" : "http://${my.host.name}:8180/auth", "auth-server-url" : "http://localhost:8180/auth",
"ssl-required" : "external", "ssl-required" : "external",
"credentials" : { "credentials" : {
"secret": "password" "secret": "password"

View file

@ -22,7 +22,7 @@
"value" : "password" } "value" : "password" }
], ],
"realmRoles": [ "user" ], "realmRoles": [ "user" ],
"applicationRoles": { "clientRoles": {
"multi-tenant": [ "user" ] "multi-tenant": [ "user" ]
} }
}, },
@ -37,7 +37,7 @@
"value" : "user-tenant1" } "value" : "user-tenant1" }
], ],
"realmRoles": [ "user" ], "realmRoles": [ "user" ],
"applicationRoles": { "clientRoles": {
"multi-tenant": [ "user" ] "multi-tenant": [ "user" ]
} }
} }
@ -61,20 +61,10 @@
{ {
"clientId": "multi-tenant", "clientId": "multi-tenant",
"enabled": true, "enabled": true,
"adminUrl": "/multi-tenant", "adminUrl": "/multi-tenant/tenant1",
"baseUrl": "/multi-tenant", "baseUrl": "/multi-tenant/tenant1",
"redirectUris": [ "redirectUris": [
"/multi-tenant/*" "/multi-tenant/tenant1/*"
],
"secret": "password"
},
{
"clientId": "multitenant",
"enabled": true,
"adminUrl": "/multitenant/tenant1",
"baseUrl": "/multitenant/tenant1",
"redirectUris": [
"/multitenant/tenant1/*"
], ],
"secret": "password" "secret": "password"
} }

View file

@ -22,7 +22,7 @@
"value" : "password" } "value" : "password" }
], ],
"realmRoles": [ "user" ], "realmRoles": [ "user" ],
"applicationRoles": { "clientRoles": {
"multi-tenant": [ "user" ] "multi-tenant": [ "user" ]
} }
}, },
@ -37,7 +37,7 @@
"value" : "user-tenant2" } "value" : "user-tenant2" }
], ],
"realmRoles": [ "user" ], "realmRoles": [ "user" ],
"applicationRoles": { "clientRoles": {
"multi-tenant": [ "user" ] "multi-tenant": [ "user" ]
} }
} }
@ -61,10 +61,10 @@
{ {
"clientId": "multi-tenant", "clientId": "multi-tenant",
"enabled": true, "enabled": true,
"adminUrl": "/multi-tenant", "adminUrl": "/multi-tenant/tenant2",
"baseUrl": "/multi-tenant", "baseUrl": "/multi-tenant/tenant2",
"redirectUris": [ "redirectUris": [
"/multi-tenant/*" "/multi-tenant/tenant2/*"
], ],
"secret": "password" "secret": "password"
} }

View file

@ -1,244 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import java.net.URL;
/**
* Tests Undertow Adapter
*
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
* @author <a href="mailto:john.ament@spartasystems.com">John Ament</a>
*/
public class AdapterTest {
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
AdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
URL url = getClass().getResource("/adapter-test/cust-app-keycloak.json");
createApplicationDeployment()
.name("customer-portal").contextPath("/customer-portal")
.servletClass(CustomerServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
url = getClass().getResource("/adapter-test/secure-portal-keycloak.json");
createApplicationDeployment()
.name("secure-portal").contextPath("/secure-portal")
.servletClass(CallAuthenticatedServlet.class).adapterConfigPath(url.getPath())
.role("user")
.isConstrained(false).deployApplication();
url = getClass().getResource("/adapter-test/customer-db-keycloak.json");
createApplicationDeployment()
.name("customer-db").contextPath("/customer-db")
.servletClass(CustomerDatabaseServlet.class).adapterConfigPath(url.getPath())
.role("user")
.errorPage(null).deployApplication();
createApplicationDeployment()
.name("customer-db-error-page").contextPath("/customer-db-error-page")
.servletClass(CustomerDatabaseServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
url = getClass().getResource("/adapter-test/product-keycloak.json");
createApplicationDeployment()
.name("product-portal").contextPath("/product-portal")
.servletClass(ProductServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
url = getClass().getResource("/adapter-test/product-autodetect-bearer-only-keycloak.json");
createApplicationDeployment()
.name("product-portal-autodetect-bearer-only").contextPath("/product-portal-autodetect-bearer-only")
.servletClass(ProductServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
// Test that replacing system properties works for adapters
System.setProperty("app.server.base.url", "http://localhost:8081");
System.setProperty("my.host.name", "localhost");
url = getClass().getResource("/adapter-test/session-keycloak.json");
createApplicationDeployment()
.name("session-portal").contextPath("/session-portal")
.servletClass(SessionServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
url = getClass().getResource("/adapter-test/input-keycloak.json");
createApplicationDeployment()
.name("input-portal").contextPath("/input-portal")
.servletClass(InputServlet.class).adapterConfigPath(url.getPath())
.role("user").constraintUrl("/secured/*").deployApplication();
url = getClass().getResource("/adapter-test/no-access-token.json");
createApplicationDeployment()
.name("no-access-token").contextPath("/no-access-token")
.servletClass(InputServlet.class).adapterConfigPath(url.getPath())
.role("user").constraintUrl("/secured/*").deployApplication();
}
};
@Rule
public AdapterTestStrategy testStrategy = new AdapterTestStrategy("http://localhost:8081/auth", "http://localhost:8081", keycloakRule);
//@Test
public void testUi() throws Exception {
Thread.sleep(1000000000);
}
@Test
public void testLoginSSOAndLogout() throws Exception {
testStrategy.testLoginSSOMax();
testStrategy.testLoginSSOAndLogout();
}
@Test
public void testLoginEncodedRedirectUri() throws Exception {
testStrategy.testLoginEncodedRedirectUri();
}
@Test
public void testSavedPostRequest() throws Exception {
testStrategy.testSavedPostRequest();
}
@Test
public void testServletRequestLogout() throws Exception {
testStrategy.testServletRequestLogout();
}
@Test
public void testLoginSSOIdle() throws Exception {
testStrategy.testLoginSSOIdle();
}
@Test
public void testLoginSSOIdleRemoveExpiredUserSessions() throws Exception {
testStrategy.testLoginSSOIdleRemoveExpiredUserSessions();
}
@Test
public void testLoginSSOMax() throws Exception {
testStrategy.testLoginSSOMax();
}
/**
* KEYCLOAK-518
* @throws Exception
*/
@Test
public void testNullBearerToken() throws Exception {
testStrategy.testNullBearerToken();
}
/**
* KEYCLOAK-1368
* @throws Exception
*/
@Test
public void testNullBearerTokenCustomErrorPage() throws Exception {
testStrategy.testNullBearerTokenCustomErrorPage();
}
@Test
public void testAutodetectBearerOnly() throws Exception {
testStrategy.testAutodetectBearerOnly();
}
@Test
public void testBasicAuthErrorHandling() throws Exception {
testStrategy.testBasicAuthErrorHandling();
}
/**
* KEYCLOAK-518
* @throws Exception
*/
@Test
public void testBadUser() throws Exception {
testStrategy.testBadUser();
}
@Test
public void testAuthenticated() throws Exception {
testStrategy.testAuthenticated();
}
/**
* KEYCLOAK-732
*
* @throws Throwable
*/
@Test
public void testSingleSessionInvalidated() throws Throwable {
testStrategy.testSingleSessionInvalidated();
}
/**
* KEYCLOAK-741
*/
@Test
public void testSessionInvalidatedAfterFailedRefresh() throws Throwable {
testStrategy.testSessionInvalidatedAfterFailedRefresh();
}
/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
testStrategy.testAdminApplicationLogout();
}
/**
* KEYCLOAK-1216
*/
@Test
public void testAccountManagementSessionsLogout() throws Throwable {
testStrategy.testAccountManagementSessionsLogout();
}
/**
* KEYCLOAK-1733
*/
@Test
public void testNullQueryParameterAccessToken() throws Exception {
testStrategy.testNullQueryParameterAccessToken();
}
@Test
public void testRestCallWithAccessTokenAsQueryParameter() throws Exception {
testStrategy.testRestCallWithAccessTokenAsQueryParameter();
}
@Test
public void testCallURLWithAccessToken() throws Exception {
testStrategy.checkThatAccessTokenCanBeSentPublicly();
}
}

View file

@ -1,56 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import org.keycloak.KeycloakSecurityContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class CallAuthenticatedServlet extends HttpServlet {
private static final String LINK = "<a href=\"%s\" id=\"%s\">%s</a>";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (!req.authenticate(resp)) {
return;
}
KeycloakSecurityContext sc = (KeycloakSecurityContext)req.getAttribute(KeycloakSecurityContext.class.getName());
Assert.assertNotNull(sc);
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", "Customer Portal");
pw.println("Stian Thorgersen");
pw.println("Bill Burke");
pw.print("</body></html>");
pw.flush();
}
}

View file

@ -1,219 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.common.util.Time;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.KeycloakServer;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.core.UriBuilder;
import java.net.URL;
/**
* KEYCLOAK-702
*
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class CookieTokenStoreAdapterTest {
public static final String LOGIN_URL = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri("http://localhost:8081/auth")).build("demo").toString();
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
// Other tests may left Time offset uncleared, which could cause issues
Time.setOffset(0);
RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm.json"), RealmRepresentation.class);
manager.importRealm(representation);
URL url = getClass().getResource("/adapter-test/cust-app-keycloak.json");
createApplicationDeployment()
.name("customer-portal").contextPath("/customer-portal")
.servletClass(CustomerServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
url = getClass().getResource("/adapter-test/cust-app-cookie-keycloak.json");
createApplicationDeployment()
.name("customer-cookie-portal").contextPath("/customer-cookie-portal")
.servletClass(CustomerServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
url = getClass().getResource("/adapter-test/customer-db-keycloak.json");
createApplicationDeployment()
.name("customer-db").contextPath("/customer-db")
.servletClass(CustomerDatabaseServlet.class).adapterConfigPath(url.getPath())
.role("user")
.errorPage(null).deployApplication();
}
};
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected WebDriver driver;
@WebResource
protected OAuthClient oauth;
@WebResource
protected LoginPage loginPage;
@Test
public void testTokenInCookieSSO() throws Throwable {
// Login
String tokenCookie = loginToCustomerCookiePortal();
// SSO to second app
driver.navigate().to("http://localhost:8081/customer-portal");
assertLogged();
// return to customer-cookie-portal and assert still same cookie (accessToken didn't expire)
driver.navigate().to("http://localhost:8081/customer-cookie-portal");
assertLogged();
String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
Assert.assertEquals(tokenCookie, tokenCookie2);
// Logout with httpServletRequest
logoutFromCustomerCookiePortal();
// Also should be logged-out from the second app
driver.navigate().to("http://localhost:8081/customer-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
}
@Test
public void testTokenInCookieRefresh() throws Throwable {
try {
// Set token timeout 1 sec
KeycloakSession session = keycloakRule.startSession();
RealmModel realm = session.realms().getRealmByName("demo");
int originalTokenTimeout = realm.getAccessTokenLifespan();
realm.setAccessTokenLifespan(3);
session.getTransactionManager().commit();
session.close();
// login to customer-cookie-portal
String tokenCookie1 = loginToCustomerCookiePortal();
// Simulate waiting 4 seconds (Running testsuite in real env like Wildfly or EAP may still require to do Thread.sleep to really wait 4 seconds...)
Time.setOffset(4);
//Thread.sleep(4000);
// assert cookie was refreshed
driver.navigate().to("http://localhost:8081/customer-cookie-portal");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-cookie-portal");
assertLogged();
String tokenCookie2 = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
Assert.assertNotEquals(tokenCookie1, tokenCookie2);
// login to 2nd app and logout from it
driver.navigate().to("http://localhost:8081/customer-portal");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-portal");
assertLogged();
driver.navigate().to("http://localhost:8081/customer-portal/logout");
Assert.assertTrue(driver.getPageSource().contains("servlet logout ok"));
driver.navigate().to("http://localhost:8081/customer-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
// Simulate another 4 seconds
Time.setOffset(8);
// assert not logged in customer-cookie-portal
driver.navigate().to("http://localhost:8081/customer-cookie-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
// Change timeout back
Time.setOffset(0);
session = keycloakRule.startSession();
realm = session.realms().getRealmByName("demo");
realm.setAccessTokenLifespan(originalTokenTimeout);
session.getTransactionManager().commit();
session.close();
} finally {
Time.setOffset(0);
}
}
@Test
public void testInvalidTokenCookie() throws Throwable {
// Login
String tokenCookie = loginToCustomerCookiePortal();
String changedTokenCookie = tokenCookie.replace("a", "b");
// change cookie to invalid value
driver.manage().addCookie(new Cookie(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE, changedTokenCookie, "/customer-cookie-portal"));
// visit page and assert re-logged and cookie was refreshed
driver.navigate().to("http://localhost:8081/customer-cookie-portal");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-cookie-portal");
String currentCookie = driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
Assert.assertNotEquals(currentCookie, tokenCookie);
Assert.assertNotEquals(currentCookie, changedTokenCookie);
// logout
logoutFromCustomerCookiePortal();
}
// login to customer-cookie-portal and return the KEYCLOAK_ADAPTER_STATE cookie established on adapter
private String loginToCustomerCookiePortal() {
driver.navigate().to("http://localhost:8081/customer-cookie-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
loginPage.login("bburke@redhat.com", "password");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-cookie-portal");
assertLogged();
// Assert no JSESSIONID cookie
Assert.assertNull(driver.manage().getCookieNamed("JSESSIONID"));
return driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE).getValue();
}
private void logoutFromCustomerCookiePortal() {
driver.navigate().to("http://localhost:8081/customer-cookie-portal/logout");
Assert.assertTrue(driver.getPageSource().contains("servlet logout ok"));
Assert.assertNull(driver.manage().getCookieNamed(AdapterConstants.KEYCLOAK_ADAPTER_STATE_COOKIE));
driver.navigate().to("http://localhost:8081/customer-cookie-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
}
private void assertLogged() {
String pageSource = driver.getPageSource();
Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
}
}

View file

@ -1,54 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.Principal;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class CustomerDatabaseServlet extends HttpServlet {
private static final String LINK = "<a href=\"%s\" id=\"%s\">%s</a>";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// test that bearer token auth never has an HTTP session created
Assert.assertNull(req.getSession(false));
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
Principal principal = req.getUserPrincipal();
Assert.assertNotNull(principal);
pw.printf("<html><head><title>%s</title></head><body>", "Customer Portal");
pw.println("Stian Thorgersen");
pw.println("Bill Burke");
pw.print("</body></html>");
pw.flush();
}
}

View file

@ -1,85 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class CustomerServlet extends HttpServlet {
private static final String LINK = "<a href=\"%s\" id=\"%s\">%s</a>";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter pw = resp.getWriter();
if (req.getRequestURI().toString().endsWith("logout")) {
resp.setStatus(200);
pw.println("servlet logout ok");
// Call logout before pw.flush
req.logout();
pw.flush();
return;
}
KeycloakSecurityContext context = (KeycloakSecurityContext)req.getAttribute(KeycloakSecurityContext.class.getName());
Client client = ClientBuilder.newClient();
try {
String appBase = System.getProperty("app.server.base.url", "http://localhost:8081");
WebTarget target = client.target(appBase + "/customer-db/");
Response response = target.request().get();
Assert.assertEquals(401, response.getStatus());
response.close();
// Assert not possible to authenticate with refresh token
RefreshableKeycloakSecurityContext refreshableContext = (RefreshableKeycloakSecurityContext) context;
response = target.request()
.header(HttpHeaders.AUTHORIZATION, "Bearer " + refreshableContext.getRefreshToken())
.get();
Assert.assertEquals(401, response.getStatus());
response.close();
String html = target.request()
.header(HttpHeaders.AUTHORIZATION, "Bearer " + context.getTokenString())
.get(String.class);
resp.setContentType("text/html");
pw.println(html);
pw.flush();
} finally {
client.close();
}
}
}

View file

@ -1,203 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import java.net.URL;
import java.security.PublicKey;
/**
* Tests Undertow Adapter
*
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
*/
public class FilterAdapterTest {
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
AdapterTestStrategy.baseAdapterTestInitialization(session, manager, adminRealm, getClass());
URL url = getClass().getResource("/adapter-test/cust-app-keycloak.json");
createApplicationDeployment()
.name("customer-portal").contextPath("/customer-portal")
.servletClass(CustomerServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplicationWithFilter();
url = getClass().getResource("/adapter-test/secure-portal-keycloak.json");
createApplicationDeployment()
.name("secure-portal").contextPath("/secure-portal")
.servletClass(CallAuthenticatedServlet.class).adapterConfigPath(url.getPath())
.role("user")
.isConstrained(false).deployApplicationWithFilter();
url = getClass().getResource("/adapter-test/customer-db-keycloak.json");
createApplicationDeployment()
.name("customer-db").contextPath("/customer-db")
.servletClass(CustomerDatabaseServlet.class).adapterConfigPath(url.getPath())
.role("user")
.errorPage(null).deployApplicationWithFilter();
createApplicationDeployment()
.name("customer-db-error-page").contextPath("/customer-db-error-page")
.servletClass(CustomerDatabaseServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplicationWithFilter();
url = getClass().getResource("/adapter-test/product-keycloak.json");
createApplicationDeployment()
.name("product-portal").contextPath("/product-portal")
.servletClass(ProductServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplicationWithFilter();
// Test that replacing system properties works for adapters
System.setProperty("app.server.base.url", "http://localhost:8081");
System.setProperty("my.host.name", "localhost");
url = getClass().getResource("/adapter-test/session-keycloak.json");
createApplicationDeployment()
.name("session-portal").contextPath("/session-portal")
.servletClass(SessionServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplicationWithFilter();
url = getClass().getResource("/adapter-test/input-keycloak.json");
createApplicationDeployment()
.name("input-portal").contextPath("/input-portal")
.servletClass(InputServlet.class).adapterConfigPath(url.getPath())
.role("user").constraintUrl("/secured/*").deployApplicationWithFilter();
}
};
@Rule
public AdapterTestStrategy testStrategy = new AdapterTestStrategy("http://localhost:8081/auth", "http://localhost:8081", keycloakRule);
@Test
public void testLoginSSOAndLogout() throws Exception {
testStrategy.testLoginSSOAndLogout();
}
@Test
public void testSavedPostRequest() throws Exception {
System.setProperty("insecure.user.principal.unsupported", "true");
testStrategy.testSavedPostRequest();
}
@Test
public void testServletRequestLogout() throws Exception {
testStrategy.testServletRequestLogout();
}
@Test
public void testLoginSSOIdle() throws Exception {
testStrategy.testLoginSSOIdle();
}
@Test
public void testLoginSSOIdleRemoveExpiredUserSessions() throws Exception {
testStrategy.testLoginSSOIdleRemoveExpiredUserSessions();
}
@Test
public void testLoginSSOMax() throws Exception {
testStrategy.testLoginSSOMax();
}
/**
* KEYCLOAK-518
* @throws Exception
*/
@Test
public void testNullBearerToken() throws Exception {
testStrategy.testNullBearerToken();
}
/**
* KEYCLOAK-1368
* @throws Exception
*/
/*
can't test because of the way filter works
@Test
public void testNullBearerTokenCustomErrorPage() throws Exception {
testStrategy.testNullBearerTokenCustomErrorPage();
}
*/
/**
* KEYCLOAK-518
* @throws Exception
*/
@Test
public void testBadUser() throws Exception {
testStrategy.testBadUser();
}
/*
Don't need to test this because HttpServletRequest.authenticate doesn't make sense with filter implementation
@Test
public void testAuthenticated() throws Exception {
testStrategy.testAuthenticated();
}
*/
/**
* KEYCLOAK-732
*
* @throws Throwable
*/
@Test
public void testSingleSessionInvalidated() throws Throwable {
testStrategy.testSingleSessionInvalidated();
}
/**
* KEYCLOAK-741
*/
@Test
public void testSessionInvalidatedAfterFailedRefresh() throws Throwable {
testStrategy.testSessionInvalidatedAfterFailedRefresh();
}
/**
* KEYCLOAK-942
*/
@Test
public void testAdminApplicationLogout() throws Throwable {
testStrategy.testAdminApplicationLogout();
}
/**
* KEYCLOAK-1216
*/
/*
Can't test this because backchannel logout for filter does not invalidate the session
@Test
public void testAccountManagementSessionsLogout() throws Throwable {
testStrategy.testAccountManagementSessionsLogout();
}
*/
}

View file

@ -1,83 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import org.keycloak.KeycloakSecurityContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
*/
public class InputServlet extends HttpServlet {
private static final String FORM_URLENCODED = "application/x-www-form-urlencoded";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String appBase = System.getProperty("app.server.base.url", "http://localhost:8081");
if (req.getRequestURI().endsWith("insecure")) {
if (System.getProperty("insecure.user.principal.unsupported") == null) Assert.assertNotNull(req.getUserPrincipal());
if (System.getProperty("insecure.user.principal.unsupported") == null) Assert.assertNotNull(req.getAttribute(KeycloakSecurityContext.class.getName()));
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", "Insecure Page");
if (req.getUserPrincipal() != null) pw.printf("UserPrincipal: " + req.getUserPrincipal().getName());
pw.print("</body></html>");
pw.flush();
return;
}
String actionUrl = appBase + "/input-portal/secured/post";
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", "Input Page");
pw.printf("<form action=\"%s\" method=\"POST\">", actionUrl);
pw.println("<input id=\"parameter\" type=\"text\" name=\"parameter\">");
pw.println("<input name=\"submit\" type=\"submit\" value=\"Submit\"></form>");
pw.print("</body></html>");
pw.flush();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if (!FORM_URLENCODED.equals(req.getContentType())) {
resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
PrintWriter pw = resp.getWriter();
resp.setContentType("text/plain");
pw.printf("Expecting content type " + FORM_URLENCODED +
", received " + req.getContentType() + " instead");
pw.flush();
return;
}
resp.setContentType("text/plain");
PrintWriter pw = resp.getWriter();
pw.printf("parameter="+req.getParameter("parameter"));
pw.flush();
}
}

View file

@ -1,154 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.KeycloakServer;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.core.UriBuilder;
/**
*
* @author Juraci Paixão Kröhling <juraci at kroehling.de>
*/
public class MultiTenancyTest {
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected LoginPage loginPage;
@WebResource
protected WebDriver driver;
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
RealmRepresentation tenant1 = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/tenant1-realm.json"), RealmRepresentation.class);
manager.importRealm(tenant1);
RealmRepresentation tenant2 = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/tenant2-realm.json"), RealmRepresentation.class);
manager.importRealm(tenant2);
createApplicationDeployment()
.name("multi-tenant").contextPath("/multi-tenant")
.servletClass(MultiTenantServlet.class)
.role("user")
.keycloakConfigResolver(MultiTenantResolver.class).deployApplication();
}
protected String[] getTestRealms() {
return new String[]{"test", "demo", "tenant1", "tenant2"};
}
};
/**
* Simplest scenario: one user, one realm. The user is not logged in at
* any other realm
* @throws Exception
*/
@Test
public void testTenantsLoggingOut() throws Exception {
doTenantRequests("tenant1", true);
doTenantRequests("tenant2", true);
}
/**
* This tests the adapter's ability to deal with multiple sessions
* from the same user, one for each realm. It should not mixup and return
* a session from tenant1 to tenant2
* @throws Exception
*/
@Test
public void testTenantsWithoutLoggingOut() throws Exception {
doTenantRequests("tenant1", true);
doTenantRequests("tenant2", true);
doTenantRequests("tenant1", false);
doTenantRequests("tenant2", true);
}
/**
* This test simulates an user that is not logged in yet, and tris to login
* into tenant1 using an account from tenant2.
* On this scenario, the user should be shown the login page again.
*
* @throws Exception
*/
@Test
public void testUnauthorizedAccessNotLoggedIn() throws Exception {
String keycloakServerBaseUrl = "http://localhost:8081/auth";
driver.navigate().to("http://localhost:8081/multi-tenant?realm=tenant1");
Assert.assertTrue(driver.getCurrentUrl().startsWith(keycloakServerBaseUrl));
loginPage.login("user-tenant2", "user-tenant2");
Assert.assertTrue(driver.getCurrentUrl().startsWith(keycloakServerBaseUrl));
}
/**
* This test simulates an user which is already logged in into tenant1
* and tries to access a resource on tenant2.
* On this scenario, the user should be shown the login page again.
*
* @throws Exception
*/
@Test
public void testUnauthorizedAccessLoggedIn() throws Exception {
String keycloakServerBaseUrl = "http://localhost:8081/auth";
doTenantRequests("tenant1", false);
driver.navigate().to("http://localhost:8081/multi-tenant?realm=tenant2");
Assert.assertTrue(driver.getCurrentUrl().startsWith(keycloakServerBaseUrl));
}
private void doTenantRequests(String tenant, boolean logout) {
String tenantLoginUrl = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri("http://localhost:8081/auth")).build(tenant).toString();
driver.navigate().to("http://localhost:8081/multi-tenant?realm="+tenant);
System.out.println("Current url: " + driver.getCurrentUrl());
Assert.assertTrue(driver.getCurrentUrl().startsWith(tenantLoginUrl));
loginPage.login("bburke@redhat.com", "password");
System.out.println("Current url: " + driver.getCurrentUrl());
Assert.assertEquals("http://localhost:8081/multi-tenant?realm="+tenant, driver.getCurrentUrl());
String pageSource = driver.getPageSource();
System.out.println(pageSource);
Assert.assertTrue(pageSource.contains("Username: bburke@redhat.com"));
Assert.assertTrue(pageSource.contains("Realm: "+tenant));
if (logout) {
driver.manage().deleteAllCookies();
}
}
}

View file

@ -1,41 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;
import org.keycloak.adapters.spi.HttpFacade;
import java.io.InputStream;
/**
*
* @author Juraci Paixão Kröhling <juraci at kroehling.de>
*/
public class MultiTenantResolver implements KeycloakConfigResolver {
@Override
public KeycloakDeployment resolve(HttpFacade.Request request) {
String realm = request.getQueryParamValue("realm");
InputStream is = getClass().getResourceAsStream("/adapter-test/"+realm+"-keycloak.json");
KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(is);
return deployment;
}
}

View file

@ -1,48 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.keycloak.KeycloakSecurityContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
*
* @author Juraci Paixão Kröhling <juraci at kroehling.de>
*/
public class MultiTenantServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
KeycloakSecurityContext context = (KeycloakSecurityContext)req.getAttribute(KeycloakSecurityContext.class.getName());
pw.print("Username: ");
pw.println(context.getIdToken().getPreferredUsername());
pw.print("<br/>Realm: ");
pw.println(context.getRealm());
pw.flush();
}
}

View file

@ -1,49 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class ProductServlet extends HttpServlet {
private static final String LINK = "<a href=\"%s\" id=\"%s\">%s</a>";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", "Product Portal");
pw.println("iPhone");
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.flush();
}
}

View file

@ -1,160 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.KeycloakServer;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.core.UriBuilder;
import java.net.URL;
import java.security.PublicKey;
import java.util.List;
import java.util.Map;
/**
* Tests Undertow Adapter
*
* Also tests relative URIs in the adapter and valid redirect uris.
* Also tests adapters not configured with public key
*
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
*/
public class RelativeUriAdapterTest {
public static final String LOGIN_URL = OIDCLoginProtocolService.authUrl(UriBuilder.fromUri("http://localhost:8081/auth")).build("demo").toString();
@ClassRule
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){
@Override
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
RealmRepresentation representation = KeycloakServer.loadJson(getClass().getResourceAsStream("/adapter-test/demorealm-relative.json"), RealmRepresentation.class);
manager.importRealm(representation);
URL url = getClass().getResource("/adapter-test/cust-app-keycloak-relative.json");
createApplicationDeployment()
.name("customer-portal").contextPath("/customer-portal")
.servletClass(CustomerServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
url = getClass().getResource("/adapter-test/customer-db-keycloak-relative.json");
createApplicationDeployment()
.name("customer-db").contextPath("/customer-db")
.servletClass(CustomerDatabaseServlet.class).adapterConfigPath(url.getPath())
.role("user")
.errorPage(null).deployApplication();
url = getClass().getResource("/adapter-test/product-keycloak-relative.json");
createApplicationDeployment()
.name("product-portal").contextPath("/product-portal")
.servletClass(ProductServlet.class).adapterConfigPath(url.getPath())
.role("user").deployApplication();
}
};
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected WebDriver driver;
@WebResource
protected OAuthClient oauth;
@WebResource
protected LoginPage loginPage;
@Test
public void testLoginSSOAndLogout() throws Exception {
// test login to customer-portal which does a bearer request to customer-db
driver.navigate().to("http://localhost:8081/customer-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
loginPage.login("bburke@redhat.com", "password");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-portal");
String pageSource = driver.getPageSource();
Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
// test SSO
driver.navigate().to("http://localhost:8081/product-portal");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/product-portal");
pageSource = driver.getPageSource();
Assert.assertTrue(pageSource.contains("iPhone") && pageSource.contains("iPad"));
// View stats
List<Map<String, String>> stats = Keycloak.getInstance("http://localhost:8081/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID).realm("demo").getClientSessionStats();
Map<String, String> customerPortalStats = null;
Map<String, String> productPortalStats = null;
for (Map<String, String> s : stats) {
if (s.get("clientId").equals("customer-portal")) {
customerPortalStats = s;
} else if (s.get("clientId").equals("product-portal")) {
productPortalStats = s;
}
}
Assert.assertEquals(1, Integer.parseInt(customerPortalStats.get("active")));
Assert.assertEquals(1, Integer.parseInt(productPortalStats.get("active")));
// test logout
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri("http://localhost:8081/auth"))
.queryParam(OAuth2Constants.REDIRECT_URI, "/customer-portal").build("demo").toString();
driver.navigate().to(logoutUri);
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
driver.navigate().to("http://localhost:8081/product-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
driver.navigate().to("http://localhost:8081/customer-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
}
@Test
public void testServletRequestLogout() throws Exception {
driver.navigate().to("http://localhost:8081/customer-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
loginPage.login("bburke@redhat.com", "password");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/customer-portal");
Assert.assertTrue(driver.getPageSource().contains("Bill Burke"));
driver.navigate().to("http://localhost:8081/product-portal");
Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/product-portal");
Assert.assertTrue(driver.getPageSource().contains("iPhone"));
// test logout
driver.navigate().to("http://localhost:8081/customer-portal/logout");
Assert.assertTrue(driver.getPageSource().contains("servlet logout ok"));
driver.navigate().to("http://localhost:8081/customer-portal");
String currentUrl = driver.getCurrentUrl();
Assert.assertTrue(currentUrl.startsWith(LOGIN_URL));
driver.navigate().to("http://localhost:8081/product-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
}
}

View file

@ -1,54 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.adapter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String counter = increaseAndGetCounter(req);
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.printf("<html><head><title>%s</title></head><body>", "Session Test");
pw.printf("Counter=%s", counter);
pw.print("</body></html>");
pw.flush();
}
private String increaseAndGetCounter(HttpServletRequest req) {
HttpSession session = req.getSession();
Integer counter = (Integer)session.getAttribute("counter");
counter = (counter == null) ? 1 : counter + 1;
session.setAttribute("counter", counter);
return String.valueOf(counter);
}
}

View file

@ -14,19 +14,15 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.keycloak.testsuite.adapter; package org.keycloak.testsuite.helper.adapter;
import org.apache.http.conn.params.ConnManagerParams; import org.keycloak.testsuite.pages.InputPage;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert; import org.junit.Assert;
import org.junit.rules.ExternalResource; import org.junit.rules.ExternalResource;
import org.keycloak.OAuth2Constants; import org.keycloak.OAuth2Constants;
import org.keycloak.adapters.OIDCAuthenticationError; import org.keycloak.adapters.OIDCAuthenticationError;
import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.Keycloak;
import org.keycloak.common.Version;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
@ -34,7 +30,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.SessionTimeoutHelper; import org.keycloak.models.utils.SessionTimeoutHelper;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService; import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.keycloak.representations.VersionRepresentation;
import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
@ -65,7 +60,11 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
* Tests Undertow Adapter * Tests Jetty/Tomcat Adapter
*
* Methods from this class are used by testsuite/jetty/* and testsuite/tomcat* modules
*
* TODO: remove this when testsuite/jetty/* and testsuite/tomcat* modules will be migrated to arquillian testsuite
* *
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a> * @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
* @author <a href="mailto:john.ament@spartasystems.com">John Ament</a> * @author <a href="mailto:john.ament@spartasystems.com">John Ament</a>
@ -411,55 +410,6 @@ public class AdapterTestStrategy extends ExternalResource {
Time.setOffset(0); Time.setOffset(0);
} }
public void testAutodetectBearerOnly() throws Exception {
Client client = ClientBuilder.newClient();
// Do not redirect client to login page if it's an XHR
WebTarget target = client.target(APP_SERVER_BASE_URL + "/product-portal-autodetect-bearer-only");
Response response = target.request().header("X-Requested-With", "XMLHttpRequest").get();
Assert.assertEquals(401, response.getStatus());
response.close();
// Do not redirect client to login page if it's a partial Faces request
response = target.request().header("Faces-Request", "partial/ajax").get();
Assert.assertEquals(401, response.getStatus());
response.close();
// Do not redirect client to login page if it's a SOAP request
response = target.request().header("SOAPAction", "").get();
Assert.assertEquals(401, response.getStatus());
response.close();
// Do not redirect client to login page if Accept header is missing
response = target.request().get();
Assert.assertEquals(401, response.getStatus());
response.close();
// Do not redirect client to login page if client does not understand HTML reponses
response = target.request().header(HttpHeaders.ACCEPT, "application/json,text/xml").get();
Assert.assertEquals(401, response.getStatus());
response.close();
// Redirect client to login page if it's not an XHR
response = target.request().header("X-Requested-With", "Dont-Know").header(HttpHeaders.ACCEPT, "*/*").get();
Assert.assertEquals(302, response.getStatus());
Assert.assertTrue(response.getHeaderString(HttpHeaders.LOCATION).contains("response_type=code"));
response.close();
// Redirect client to login page if client explicitely understands HTML responses
response = target.request().header(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9").get();
Assert.assertEquals(302, response.getStatus());
Assert.assertTrue(response.getHeaderString(HttpHeaders.LOCATION).contains("response_type=code"));
response.close();
// Redirect client to login page if client understands all response types
response = target.request().header(HttpHeaders.ACCEPT, "*/*").get();
Assert.assertEquals(302, response.getStatus());
Assert.assertTrue(response.getHeaderString(HttpHeaders.LOCATION).contains("response_type=code"));
response.close();
client.close();
}
/** /**
* KEYCLOAK-518 * KEYCLOAK-518
* @throws Exception * @throws Exception
@ -477,26 +427,6 @@ public class AdapterTestStrategy extends ExternalResource {
} }
/**
* KEYCLOAK-1733
*
* @throws Exception
*/
public void testNullQueryParameterAccessToken() throws Exception {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(APP_SERVER_BASE_URL + "/customer-db/");
Response response = target.request().get();
Assert.assertEquals(401, response.getStatus());
response.close();
target = client.target(APP_SERVER_BASE_URL + "/customer-db?access_token=");
response = target.request().get();
Assert.assertEquals(401, response.getStatus());
response.close();
client.close();
}
/** /**
* KEYCLOAK-1368 * KEYCLOAK-1368
* @throws Exception * @throws Exception
@ -542,29 +472,6 @@ public class AdapterTestStrategy extends ExternalResource {
} }
/**
* KEYCLOAK-3016
* @throws Exception
*/
public void testBasicAuthErrorHandling() throws Exception {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(APP_SERVER_BASE_URL + "/customer-db/");
Response response = target.request().get();
Assert.assertEquals(401, response.getStatus());
response.close();
// The number of iterations should be HttpClient's connection pool size + 1.
final int LIMIT = ConnManagerParams.DEFAULT_MAX_TOTAL_CONNECTIONS + 1;
for (int i = 0; i < LIMIT; i++) {
System.out.println("Testing Basic Auth with bad credentials " + i);
response = target.request().header(HttpHeaders.AUTHORIZATION, "Basic dXNlcm5hbWU6cGFzc3dvcmQ=").get();
Assert.assertEquals(401, response.getStatus());
response.close();
}
client.close();
}
/** /**
* KEYCLOAK-518 * KEYCLOAK-518
* @throws Exception * @throws Exception
@ -587,77 +494,6 @@ public class AdapterTestStrategy extends ExternalResource {
client.close(); client.close();
} }
public void testAuthenticated() throws Exception {
// test login to customer-portal which does a bearer request to customer-db
driver.navigate().to(APP_SERVER_BASE_URL + "/secure-portal");
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 + "/secure-portal" + slash);
String pageSource = driver.getPageSource();
System.out.println(pageSource);
Assert.assertTrue(pageSource.contains("Bill Burke") && pageSource.contains("Stian Thorgersen"));
// test logout
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(AUTH_SERVER_URL))
.queryParam(OAuth2Constants.REDIRECT_URI, APP_SERVER_BASE_URL + "/secure-portal").build("demo").toString();
driver.navigate().to(logoutUri);
String currentUrl = driver.getCurrentUrl();
pageSource = driver.getPageSource();
Assert.assertTrue(currentUrl.startsWith(LOGIN_URL));
driver.navigate().to(APP_SERVER_BASE_URL + "/secure-portal");
Assert.assertTrue(driver.getCurrentUrl().startsWith(LOGIN_URL));
}
/**
* KEYCLOAK-1733
*
* @throws Exception
*/
public void testRestCallWithAccessTokenAsQueryParameter() throws Exception {
String accessToken = getAccessToken();
Client client = ClientBuilder.newClient();
try {
// test without token
Response response = client.target(APP_SERVER_BASE_URL + "/customer-db").request().get();
Assert.assertEquals(401, response.getStatus());
response.close();
// test with access_token as QueryParamter
response = client.target(APP_SERVER_BASE_URL + "/customer-db").queryParam("access_token", accessToken).request().get();
Assert.assertEquals(200, response.getStatus());
response.close();
} finally {
client.close();
}
}
private String getAccessToken() throws JSONException {
String tokenUrl = AUTH_SERVER_URL + "/realms/demo/protocol/openid-connect/token";
Client client = ClientBuilder.newClient();
try {
WebTarget webTarget = client.target(tokenUrl);
Form form = new Form();
form.param("grant_type", "password");
form.param("client_id", "customer-portal-public");
form.param("username", "bburke@redhat.com");
form.param("password", "password");
Response response = webTarget.request().post(Entity.form(form));
Assert.assertEquals(200, response.getStatus());
JSONObject jsonObject = new JSONObject(response.readEntity(String.class));
System.out.println(jsonObject);
response.close();
return jsonObject.getString("access_token");
} finally {
client.close();
}
}
/** /**
* KEYCLOAK-732 * KEYCLOAK-732
@ -803,14 +639,4 @@ public class AdapterTestStrategy extends ExternalResource {
Assert.assertTrue(pageSource.contains("Counter=2")); Assert.assertTrue(pageSource.contains("Counter=2"));
} }
void checkThatAccessTokenCanBeSentPublicly() {
// test login to customer-portal which does a bearer request to customer-db
final String applicationURL = APP_SERVER_BASE_URL + "/no-access-token?access_token=invalid_token";
driver.navigate().to(applicationURL);
System.out.println("Current url: " + driver.getCurrentUrl());
Assert.assertEquals(applicationURL, driver.getCurrentUrl());
inputPage.execute("hello");
}
} }

View file

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.keycloak.testsuite.adapter; package org.keycloak.testsuite.pages;
import org.keycloak.testsuite.pages.AbstractPage; import org.keycloak.testsuite.pages.AbstractPage;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;

View file

@ -218,6 +218,12 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>integration-arquillian-test-apps-servlets</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId> <artifactId>jetty-util</artifactId>

View file

@ -28,7 +28,7 @@ import org.junit.Test;
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;
import org.keycloak.testsuite.adapter.AdapterTestStrategy; import org.keycloak.testsuite.helper.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import java.io.File; import java.io.File;

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.InputServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.ProductServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.ProductServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CallAuthenticatedServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.SessionServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.SessionServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -218,6 +218,12 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>integration-arquillian-test-apps-servlets</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId> <artifactId>jetty-util</artifactId>

View file

@ -28,7 +28,7 @@ import org.junit.Test;
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;
import org.keycloak.testsuite.adapter.AdapterTestStrategy; import org.keycloak.testsuite.helper.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import java.io.File; import java.io.File;

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.InputServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.ProductServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.ProductServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CallAuthenticatedServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.SessionServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.SessionServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -218,6 +218,12 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>integration-arquillian-test-apps-servlets</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaas</artifactId> <artifactId>jetty-jaas</artifactId>

View file

@ -28,7 +28,7 @@ import org.junit.Test;
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;
import org.keycloak.testsuite.adapter.AdapterTestStrategy; import org.keycloak.testsuite.helper.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import java.io.File; import java.io.File;

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.InputServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.ProductServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.ProductServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CallAuthenticatedServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.SessionServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.SessionServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -218,6 +218,12 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>integration-arquillian-test-apps-servlets</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaas</artifactId> <artifactId>jetty-jaas</artifactId>

View file

@ -28,7 +28,7 @@ import org.junit.Test;
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;
import org.keycloak.testsuite.adapter.AdapterTestStrategy; import org.keycloak.testsuite.helper.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import java.io.File; import java.io.File;

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerDatabaseServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerDatabaseServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CustomerServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CustomerServlet</servlet-class>
</servlet> </servlet>
<servlet> <servlet>
<servlet-name>Error Servlet</servlet-name> <servlet-name>Error Servlet</servlet-name>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.InputServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.InputServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.ProductServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.ProductServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.CallAuthenticatedServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.CallAuthenticatedServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -25,7 +25,7 @@
<servlet> <servlet>
<servlet-name>Servlet</servlet-name> <servlet-name>Servlet</servlet-name>
<servlet-class>org.keycloak.testsuite.adapter.SessionServlet</servlet-class> <servlet-class>org.keycloak.testsuite.adapter.servlet.SessionServlet</servlet-class>
</servlet> </servlet>
<servlet-mapping> <servlet-mapping>

View file

@ -218,6 +218,12 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.keycloak.testsuite</groupId>
<artifactId>integration-arquillian-test-apps-servlets</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaas</artifactId> <artifactId>jetty-jaas</artifactId>

View file

@ -28,7 +28,7 @@ import org.junit.Test;
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;
import org.keycloak.testsuite.adapter.AdapterTestStrategy; import org.keycloak.testsuite.helper.adapter.AdapterTestStrategy;
import org.keycloak.testsuite.rule.AbstractKeycloakRule; import org.keycloak.testsuite.rule.AbstractKeycloakRule;
import java.io.File; import java.io.File;

Some files were not shown because too many files have changed in this diff Show more