Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
cc24484eaf
134 changed files with 1127 additions and 1786 deletions
|
@ -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(
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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("---------------------------------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
}
|
|
@ -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 {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -141,7 +141,8 @@
|
||||||
"redirectUris": [
|
"redirectUris": [
|
||||||
"/customer-portal/*"
|
"/customer-portal/*"
|
||||||
],
|
],
|
||||||
"secret": "password"
|
"secret": "password",
|
||||||
|
"directAccessGrantsEnabled": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"clientId": "customer-portal-subsystem",
|
"clientId": "customer-portal-subsystem",
|
||||||
|
|
|
@ -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" : {
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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"
|
||||||
},
|
},
|
|
@ -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>
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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;
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue