Merge pull request #3084 from mhajas/KEYCLOAK-3165
KEYCLOAK-3165 Migrate SAML Filter tests to integration arquillian testsuite
This commit is contained in:
commit
b0c7746eeb
28 changed files with 394 additions and 117 deletions
|
@ -69,6 +69,11 @@
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jboss.shrinkwrap.resolver</groupId>
|
||||||
|
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jboss.arquillian.extension</groupId>
|
<groupId>org.jboss.arquillian.extension</groupId>
|
||||||
<artifactId>arquillian-drone-bom</artifactId>
|
<artifactId>arquillian-drone-bom</artifactId>
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class BadClientSalesPostSigServlet extends SAMLServletWithLogout {
|
public class BadClientSalesPostSigServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "bad-client-sales-post-sig";
|
public static final String DEPLOYMENT_NAME = "bad-client-sales-post-sig";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class BadRealmSalesPostSigServlet extends SAMLServletWithLogout {
|
public class BadRealmSalesPostSigServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "bad-realm-sales-post-sig";
|
public static final String DEPLOYMENT_NAME = "bad-realm-sales-post-sig";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class Employee2Servlet extends SAMLServletWithLogout {
|
public class Employee2Servlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "employee2";
|
public static final String DEPLOYMENT_NAME = "employee2";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class EmployeeSigFrontServlet extends SAMLServletWithLogout {
|
public class EmployeeSigFrontServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "employee-sig-front";
|
public static final String DEPLOYMENT_NAME = "employee-sig-front";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class EmployeeSigServlet extends SAMLServletWithLogout {
|
public class EmployeeSigServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "employee-sig";
|
public static final String DEPLOYMENT_NAME = "employee-sig";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -24,11 +24,24 @@ import static org.keycloak.testsuite.util.WaitUtils.pause;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public abstract class SAMLServletWithLogout extends AbstractPageWithInjectedUrl {
|
public abstract class SAMLServlet extends AbstractPageWithInjectedUrl {
|
||||||
|
|
||||||
public void logout() {
|
public void logout() {
|
||||||
driver.navigate().to(getUriBuilder().queryParam("GLO", "true").build().toASCIIString());
|
driver.navigate().to(getUriBuilder().queryParam("GLO", "true").build().toASCIIString());
|
||||||
getUriBuilder().replaceQueryParam("GLO", null);
|
getUriBuilder().replaceQueryParam("GLO", null);
|
||||||
pause(300);
|
pause(300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void checkRoles(boolean check) {
|
||||||
|
if (check) {
|
||||||
|
getUriBuilder().queryParam("checkRoles", true);
|
||||||
|
} else {
|
||||||
|
getUriBuilder().replaceQueryParam("checkRoles", null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkRolesEndPoint() {
|
||||||
|
driver.navigate().to(getUriBuilder().build().toASCIIString() + "/checkRoles");
|
||||||
|
pause(300);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesMetadataServlet extends SAMLServletWithLogout {
|
public class SalesMetadataServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-metadata";
|
public static final String DEPLOYMENT_NAME = "sales-metadata";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesPostEncServlet extends SAMLServletWithLogout {
|
public class SalesPostEncServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-post-enc";
|
public static final String DEPLOYMENT_NAME = "sales-post-enc";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesPostPassiveServlet extends SAMLServletWithLogout {
|
public class SalesPostPassiveServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-post-passive";
|
public static final String DEPLOYMENT_NAME = "sales-post-passive";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesPostServlet extends SAMLServletWithLogout {
|
public class SalesPostServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-post";
|
public static final String DEPLOYMENT_NAME = "sales-post";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesPostSigEmailServlet extends SAMLServletWithLogout {
|
public class SalesPostSigEmailServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-post-sig-email";
|
public static final String DEPLOYMENT_NAME = "sales-post-sig-email";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesPostSigPersistentServlet extends SAMLServletWithLogout {
|
public class SalesPostSigPersistentServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-post-sig-persistent";
|
public static final String DEPLOYMENT_NAME = "sales-post-sig-persistent";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesPostSigServlet extends SAMLServletWithLogout {
|
public class SalesPostSigServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-post-sig";
|
public static final String DEPLOYMENT_NAME = "sales-post-sig";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.net.URL;
|
||||||
/**
|
/**
|
||||||
* @author mhajas
|
* @author mhajas
|
||||||
*/
|
*/
|
||||||
public class SalesPostSigTransientServlet extends SAMLServletWithLogout {
|
public class SalesPostSigTransientServlet extends SAMLServlet {
|
||||||
public static final String DEPLOYMENT_NAME = "sales-post-sig-transient";
|
public static final String DEPLOYMENT_NAME = "sales-post-sig-transient";
|
||||||
|
|
||||||
@ArquillianResource
|
@ArquillianResource
|
||||||
|
|
|
@ -17,78 +17,91 @@
|
||||||
|
|
||||||
package org.keycloak.testsuite.adapter.servlet;
|
package org.keycloak.testsuite.adapter.servlet;
|
||||||
|
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.ws.rs.*;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @author mhajas
|
||||||
*/
|
* @version $Revision: 1 $
|
||||||
public class SendUsernameServlet extends HttpServlet {
|
*/
|
||||||
|
@Path("/")
|
||||||
|
public class SendUsernameServlet {
|
||||||
|
|
||||||
public static Principal sentPrincipal;
|
private static boolean checkRoles = false;
|
||||||
public static List<String> checkRoles;
|
|
||||||
|
|
||||||
@Override
|
@Context
|
||||||
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
private HttpServletRequest httpServletRequest;
|
||||||
System.out.println("In SendUsername Servlet doGet()");
|
|
||||||
if (checkRoles != null) {
|
|
||||||
for (String role : checkRoles) {
|
|
||||||
System.out.println("check role: " + role);
|
|
||||||
//Assert.assertTrue(req.isUserInRole(role));
|
|
||||||
if (!req.isUserInRole(role)) {
|
|
||||||
resp.sendError(403);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@NoCache
|
||||||
|
public Response doGet(@QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException {
|
||||||
|
System.out.println("In SendUsername Servlet doGet() check roles is " + (checkRolesFlag || checkRoles));
|
||||||
|
if (httpServletRequest.getUserPrincipal() != null && (checkRolesFlag || checkRoles) && !checkRoles()) {
|
||||||
|
return Response.status(Response.Status.FORBIDDEN).entity("Forbidden").build();
|
||||||
}
|
}
|
||||||
resp.setContentType("text/plain");
|
|
||||||
OutputStream stream = resp.getOutputStream();
|
|
||||||
Principal principal = req.getUserPrincipal();
|
|
||||||
stream.write("request-path: ".getBytes());
|
|
||||||
stream.write(req.getServletPath().getBytes());
|
|
||||||
stream.write("\n".getBytes());
|
|
||||||
stream.write("principal=".getBytes());
|
|
||||||
if (principal == null) {
|
|
||||||
stream.write("null".getBytes());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String name = principal.getName();
|
|
||||||
stream.write(name.getBytes());
|
|
||||||
sentPrincipal = principal;
|
|
||||||
|
|
||||||
|
return Response.ok(getOutput(), MediaType.TEXT_PLAIN).build();
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
|
@POST
|
||||||
System.out.println("In SendUsername Servlet doPost()");
|
@NoCache
|
||||||
if (checkRoles != null) {
|
public Response doPost(@QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException {
|
||||||
for (String role : checkRoles) {
|
System.out.println("In SendUsername Servlet doPost() check roles is " + (checkRolesFlag || checkRoles));
|
||||||
System.out.println("check role: " + role);
|
|
||||||
if (!req.isUserInRole(role)) {
|
if (httpServletRequest.getUserPrincipal() != null && (checkRolesFlag || checkRoles) && !checkRoles()) {
|
||||||
throw new RuntimeException("User: " + req.getUserPrincipal() + " is not in Role: " + role);
|
throw new RuntimeException("User: " + httpServletRequest.getUserPrincipal() + " do not have required role");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
resp.setContentType("text/plain");
|
|
||||||
OutputStream stream = resp.getOutputStream();
|
return Response.ok(getOutput(), MediaType.TEXT_PLAIN).build();
|
||||||
Principal principal = req.getUserPrincipal();
|
}
|
||||||
stream.write("request-path: ".getBytes());
|
|
||||||
stream.write(req.getServletPath().getBytes());
|
@GET
|
||||||
stream.write("\n".getBytes());
|
@Path("{path}")
|
||||||
stream.write("principal=".getBytes());
|
public Response doGetElseWhere(@PathParam("path") String path, @QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException {
|
||||||
|
System.out.println("In SendUsername Servlet doGetElseWhere() - path: " + path);
|
||||||
|
return doGet(checkRolesFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{path}")
|
||||||
|
public Response doPostElseWhere(@PathParam("path") String path, @QueryParam("checkRoles") boolean checkRolesFlag) throws ServletException, IOException {
|
||||||
|
System.out.println("In SendUsername Servlet doPostElseWhere() - path: " + path);
|
||||||
|
return doPost(checkRolesFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("checkRoles")
|
||||||
|
public String checkRolesEndPoint() {
|
||||||
|
checkRoles = true;
|
||||||
|
System.out.println("Setting checkRoles to true");
|
||||||
|
return "Roles will be checked";
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkRoles() {
|
||||||
|
return httpServletRequest.isUserInRole("manager");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getOutput() {
|
||||||
|
String output = "request-path: ";
|
||||||
|
output += httpServletRequest.getServletPath();
|
||||||
|
output += "\n";
|
||||||
|
output += "principal=";
|
||||||
|
Principal principal = httpServletRequest.getUserPrincipal();
|
||||||
|
|
||||||
if (principal == null) {
|
if (principal == null) {
|
||||||
stream.write("null".getBytes());
|
return output + "null";
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
String name = principal.getName();
|
|
||||||
stream.write(name.getBytes());
|
return output + principal.getName();
|
||||||
sentPrincipal = principal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,9 @@ import org.jboss.logging.Logger;
|
||||||
import org.jboss.logging.Logger.Level;
|
import org.jboss.logging.Logger.Level;
|
||||||
import org.jboss.shrinkwrap.api.Archive;
|
import org.jboss.shrinkwrap.api.Archive;
|
||||||
import org.jboss.shrinkwrap.api.asset.StringAsset;
|
import org.jboss.shrinkwrap.api.asset.StringAsset;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive;
|
||||||
import org.keycloak.representations.adapters.config.AdapterConfig;
|
import org.keycloak.representations.adapters.config.AdapterConfig;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.UseServletFilter;
|
||||||
import org.keycloak.testsuite.util.IOUtil;
|
import org.keycloak.testsuite.util.IOUtil;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
@ -35,11 +37,9 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.hasAppServerContainerAnnotation;
|
|
||||||
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isRelative;
|
|
||||||
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.isTomcatAppServer;
|
|
||||||
|
|
||||||
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.*;
|
import static org.keycloak.testsuite.arquillian.AppServerTestEnricher.*;
|
||||||
|
import static org.keycloak.testsuite.arquillian.AuthServerTestEnricher.getAuthServerContextRoot;
|
||||||
import static org.keycloak.testsuite.util.IOUtil.*;
|
import static org.keycloak.testsuite.util.IOUtil.*;
|
||||||
|
|
||||||
;
|
;
|
||||||
|
@ -125,7 +125,7 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
|
||||||
adapterConfig.setAuthServerUrl(getAuthServerContextRoot() + "/auth");
|
adapterConfig.setAuthServerUrl(getAuthServerContextRoot() + "/auth");
|
||||||
adapterConfig.setRealmKey(REALM_KEY);
|
adapterConfig.setRealmKey(REALM_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("true".equals(System.getProperty("app.server.ssl.required"))) {
|
if ("true".equals(System.getProperty("app.server.ssl.required"))) {
|
||||||
adapterConfig.setSslRequired("all");
|
adapterConfig.setSslRequired("all");
|
||||||
}
|
}
|
||||||
|
@ -155,17 +155,46 @@ public class DeploymentArchiveProcessor implements ApplicationArchiveProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void modifyWebXml(Archive<?> archive, TestClass testClass) {
|
protected void modifyWebXml(Archive<?> archive, TestClass testClass) {
|
||||||
if (isTomcatAppServer(testClass.getJavaClass())) {
|
try {
|
||||||
try {
|
String webXmlContent = IOUtils.toString(
|
||||||
String webXmlContent = IOUtils.toString(
|
archive.get(WEBXML_PATH).getAsset().openStream());
|
||||||
archive.get(WEBXML_PATH).getAsset().openStream());
|
if (isTomcatAppServer(testClass.getJavaClass())) {
|
||||||
|
|
||||||
webXmlContent = webXmlContent.replace("<auth-method>KEYCLOAK</auth-method>", "<auth-method>BASIC</auth-method>");
|
webXmlContent = webXmlContent.replace("<auth-method>KEYCLOAK</auth-method>", "<auth-method>BASIC</auth-method>");
|
||||||
|
|
||||||
archive.add(new StringAsset((webXmlContent)), WEBXML_PATH);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new RuntimeException("Cannot load web.xml from archive.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (testClass.getJavaClass().isAnnotationPresent(UseServletFilter.class)) {
|
||||||
|
//We need to add filter declaration to web.xml
|
||||||
|
log.info("Adding filter to " + testClass.getAnnotation(UseServletFilter.class).filterClass() + " with mapping " + testClass.getAnnotation(UseServletFilter.class).filterPattern() + " for " + archive.getName());
|
||||||
|
String filter = "\n<filter>\n" +
|
||||||
|
"<filter-name>" + testClass.getAnnotation(UseServletFilter.class).filterName() + "</filter-name>\n" +
|
||||||
|
"<filter-class>" + testClass.getAnnotation(UseServletFilter.class).filterClass() + "</filter-class>\n" +
|
||||||
|
"</filter>\n" +
|
||||||
|
"\n<filter-mapping>\n" +
|
||||||
|
"<filter-name>" + testClass.getAnnotation(UseServletFilter.class).filterName() + "</filter-name>\n" +
|
||||||
|
"<url-pattern>" + testClass.getAnnotation(UseServletFilter.class).filterPattern() + "</url-pattern>\n";
|
||||||
|
if (!testClass.getAnnotation(UseServletFilter.class).dispatcherType().isEmpty()) {
|
||||||
|
filter += "<dispatcher>" + testClass.getAnnotation(UseServletFilter.class).dispatcherType() + "</dispatcher>\n";
|
||||||
|
}
|
||||||
|
filter += "</filter-mapping>\n";
|
||||||
|
|
||||||
|
webXmlContent = webXmlContent.replace("</module-name>", "</module-name> " + filter);
|
||||||
|
|
||||||
|
//Also we need to add all dependencies within war lib directory, because filter needs to work without installed adapter
|
||||||
|
log.info("Adding SAMLFilter dependencies to " + archive.getName());
|
||||||
|
((WebArchive) archive).addAsLibraries(new SAMLFilterDependency().getDependencies());
|
||||||
|
|
||||||
|
|
||||||
|
//finally we need to remove all keycloak related configuration from web.xml
|
||||||
|
int start = webXmlContent.indexOf("<security-constraint>");
|
||||||
|
int end = webXmlContent.indexOf("</security-role>") + "</security-role>".length();
|
||||||
|
|
||||||
|
|
||||||
|
webXmlContent = webXmlContent.substring(0, start) + webXmlContent.substring(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
archive.add(new StringAsset((webXmlContent)), WEBXML_PATH);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException("Cannot load web.xml from archive.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
package org.keycloak.testsuite.arquillian;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
|
||||||
|
import org.jboss.shrinkwrap.resolver.api.maven.PackagingType;
|
||||||
|
import org.jboss.shrinkwrap.resolver.api.maven.ScopeType;
|
||||||
|
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenDependency;
|
||||||
|
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenDependencyExclusion;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
public class SAMLFilterDependency implements MavenDependency {
|
||||||
|
|
||||||
|
private static File[] files;
|
||||||
|
|
||||||
|
protected final Logger log = org.jboss.logging.Logger.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<MavenDependencyExclusion> getExclusions() {
|
||||||
|
return Collections.EMPTY_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScopeType getScope() {
|
||||||
|
return ScopeType.COMPILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOptional() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PackagingType getPackaging() {
|
||||||
|
return PackagingType.JAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PackagingType getType() {
|
||||||
|
return PackagingType.JAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClassifier() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVersion() {
|
||||||
|
return System.getProperty("project.version");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGroupId() {
|
||||||
|
return "org.keycloak";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArtifactId() {
|
||||||
|
return "keycloak-saml-servlet-filter-adapter";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toCanonicalForm() {
|
||||||
|
return getGroupId() + ":" + getArtifactId() + ":" + getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolve() {
|
||||||
|
log.info("Resolving SAMLFilter dependencies");
|
||||||
|
files = Maven.configureResolver().addDependency(this)
|
||||||
|
.resolve().withTransitivity().asFile();
|
||||||
|
log.info("Resolving dependencies is finished with " + files.length + " files");
|
||||||
|
}
|
||||||
|
|
||||||
|
public File[] getDependencies() {
|
||||||
|
if (files == null) {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.keycloak.testsuite.arquillian.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Inherited
|
||||||
|
public @interface UseServletFilter {
|
||||||
|
|
||||||
|
String filterName();
|
||||||
|
String filterClass();
|
||||||
|
String filterPattern() default "/*";
|
||||||
|
String dispatcherType() default "";
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package org.keycloak.testsuite.adapter.servlet;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.UseServletFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
|
||||||
|
@UseServletFilter(filterName = "saml-filter", filterClass = "org.keycloak.adapters.saml.servlet.SamlFilter")
|
||||||
|
public abstract class AbstractSAMLFilterServletAdapterTest extends AbstractSAMLServletsAdapterTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void checkRoles() {
|
||||||
|
badClientSalesPostSigServletPage.checkRoles(true);
|
||||||
|
badRealmSalesPostSigServletPage.checkRoles(true);
|
||||||
|
employeeSigServletPage.checkRoles(true);
|
||||||
|
employeeSigFrontServletPage.checkRoles(true);
|
||||||
|
salesMetadataServletPage.checkRoles(true);
|
||||||
|
salesPostServletPage.checkRoles(true);
|
||||||
|
salesPostEncServletPage.checkRoles(true);
|
||||||
|
salesPostSigServletPage.checkRoles(true);
|
||||||
|
salesPostPassiveServletPage.checkRoles(true);
|
||||||
|
salesPostSigEmailServletPage.checkRoles(true);
|
||||||
|
salesPostSigPersistentServletPage.checkRoles(true);
|
||||||
|
salesPostSigTransientServletPage.checkRoles(true);
|
||||||
|
employee2ServletPage.navigateTo();
|
||||||
|
|
||||||
|
//using endpoint instead of query param because we are not able to put query param to IDP initiated login
|
||||||
|
testRealmLoginPage.form().login(bburkeUser);
|
||||||
|
employee2ServletPage.checkRolesEndPoint();
|
||||||
|
employee2ServletPage.logout();
|
||||||
|
|
||||||
|
forbiddenIfNotAuthenticated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void uncheckRoles() {
|
||||||
|
badClientSalesPostSigServletPage.checkRoles(false);
|
||||||
|
badRealmSalesPostSigServletPage.checkRoles(false);
|
||||||
|
employee2ServletPage.checkRoles(false);
|
||||||
|
employeeSigServletPage.checkRoles(false);
|
||||||
|
employeeSigFrontServletPage.checkRoles(false);
|
||||||
|
salesMetadataServletPage.checkRoles(false);
|
||||||
|
salesPostServletPage.checkRoles(false);
|
||||||
|
salesPostEncServletPage.checkRoles(false);
|
||||||
|
salesPostSigServletPage.checkRoles(false);
|
||||||
|
salesPostPassiveServletPage.checkRoles(false);
|
||||||
|
salesPostSigEmailServletPage.checkRoles(false);
|
||||||
|
salesPostSigPersistentServletPage.checkRoles(false);
|
||||||
|
salesPostSigTransientServletPage.checkRoles(false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,46 +50,48 @@ import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAdapterTest {
|
public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAdapterTest {
|
||||||
@Page
|
@Page
|
||||||
private BadClientSalesPostSigServlet badClientSalesPostSigServletPage;
|
protected BadClientSalesPostSigServlet badClientSalesPostSigServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private BadRealmSalesPostSigServlet badRealmSalesPostSigServletPage;
|
protected BadRealmSalesPostSigServlet badRealmSalesPostSigServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private Employee2Servlet employee2ServletPage;
|
protected Employee2Servlet employee2ServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private EmployeeSigServlet employeeSigServletPage;
|
protected EmployeeSigServlet employeeSigServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private EmployeeSigFrontServlet employeeSigFrontServletPage;
|
protected EmployeeSigFrontServlet employeeSigFrontServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesMetadataServlet salesMetadataServletPage;
|
protected SalesMetadataServlet salesMetadataServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesPostServlet salesPostServletPage;
|
protected SalesPostServlet salesPostServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesPostEncServlet salesPostEncServletPage;
|
protected SalesPostEncServlet salesPostEncServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesPostPassiveServlet salesPostPassiveServletPage;
|
protected SalesPostPassiveServlet salesPostPassiveServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesPostSigServlet salesPostSigServletPage;
|
protected SalesPostSigServlet salesPostSigServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesPostSigEmailServlet salesPostSigEmailServletPage;
|
protected SalesPostSigEmailServlet salesPostSigEmailServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesPostSigPersistentServlet salesPostSigPersistentServletPage;
|
protected SalesPostSigPersistentServlet salesPostSigPersistentServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SalesPostSigTransientServlet salesPostSigTransientServletPage;
|
protected SalesPostSigTransientServlet salesPostSigTransientServletPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
private SAMLIDPInitiatedLogin samlidpInitiatedLogin;
|
protected SAMLIDPInitiatedLogin samlidpInitiatedLogin;
|
||||||
|
|
||||||
|
protected boolean forbiddenIfNotAuthenticated = true;
|
||||||
|
|
||||||
@Deployment(name = BadClientSalesPostSigServlet.DEPLOYMENT_NAME)
|
@Deployment(name = BadClientSalesPostSigServlet.DEPLOYMENT_NAME)
|
||||||
protected static WebArchive badClientSalesPostSig() {
|
protected static WebArchive badClientSalesPostSig() {
|
||||||
|
@ -196,7 +198,7 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
||||||
waitUntilElement(By.xpath("//body")).text().contains("principal=bburke");
|
waitUntilElement(By.xpath("//body")).text().contains("principal=bburke");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testSuccessfulAndUnauthorizedLogin(SAMLServletWithLogout page, Login loginPage) {
|
private void testSuccessfulAndUnauthorizedLogin(SAMLServlet page, Login loginPage) {
|
||||||
assertSuccessfulLogin(page, bburkeUser, loginPage);
|
assertSuccessfulLogin(page, bburkeUser, loginPage);
|
||||||
page.logout();
|
page.logout();
|
||||||
assertForbiddenLogin(page, "unauthorized", "password", loginPage);
|
assertForbiddenLogin(page, "unauthorized", "password", loginPage);
|
||||||
|
@ -223,7 +225,6 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
||||||
assertForbidden(employee2ServletPage);
|
assertForbidden(employee2ServletPage);
|
||||||
assertForbidden(employeeSigFrontServletPage);
|
assertForbidden(employeeSigFrontServletPage);
|
||||||
assertForbidden(salesPostSigPersistentServletPage);
|
assertForbidden(salesPostSigPersistentServletPage);
|
||||||
|
|
||||||
salesPostServletPage.logout();
|
salesPostServletPage.logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,8 +244,12 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
||||||
assertCurrentUrlStartsWith(testRealmSAMLRedirectLoginPage);
|
assertCurrentUrlStartsWith(testRealmSAMLRedirectLoginPage);
|
||||||
|
|
||||||
salesPostPassiveServletPage.navigateTo();
|
salesPostPassiveServletPage.navigateTo();
|
||||||
waitUntilElement(By.xpath("//body")).text().not().contains("principal=");
|
if (forbiddenIfNotAuthenticated) {
|
||||||
assertTrue(driver.getPageSource().contains("Forbidden") || driver.getPageSource().contains("<body></body>") || driver.getPageSource().equals(""));
|
waitUntilElement(By.xpath("//body")).text().not().contains("principal=");
|
||||||
|
assertTrue(driver.getPageSource().contains("Forbidden") || driver.getPageSource().contains("<body></body>") || driver.getPageSource().equals(""));
|
||||||
|
} else {
|
||||||
|
waitUntilElement(By.xpath("//body")).text().contains("principal=null");
|
||||||
|
}
|
||||||
|
|
||||||
salesPostSigEmailServletPage.navigateTo();
|
salesPostSigEmailServletPage.navigateTo();
|
||||||
assertCurrentUrlStartsWith(testRealmSAMLPostLoginPage);
|
assertCurrentUrlStartsWith(testRealmSAMLPostLoginPage);
|
||||||
|
@ -320,9 +325,13 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
||||||
public void salesPostPassiveTest() {
|
public void salesPostPassiveTest() {
|
||||||
salesPostPassiveServletPage.navigateTo();
|
salesPostPassiveServletPage.navigateTo();
|
||||||
|
|
||||||
waitUntilElement(By.xpath("//body")).text().not().contains("principal=");
|
if (forbiddenIfNotAuthenticated) {
|
||||||
//Different 403 status page on EAP and Wildfly
|
waitUntilElement(By.xpath("//body")).text().not().contains("principal=");
|
||||||
assertTrue(driver.getPageSource().contains("Forbidden") || driver.getPageSource().contains("<body></body>") || driver.getPageSource().equals(""));
|
//Different 403 status page on EAP and Wildfly
|
||||||
|
assertTrue(driver.getPageSource().contains("Forbidden") || driver.getPageSource().contains("<body></body>") || driver.getPageSource().equals(""));
|
||||||
|
} else {
|
||||||
|
waitUntilElement(By.xpath("//body")).text().contains("principal=null");
|
||||||
|
}
|
||||||
|
|
||||||
assertSuccessfulLogin(salesPostServletPage, bburkeUser, testRealmSAMLPostLoginPage);
|
assertSuccessfulLogin(salesPostServletPage, bburkeUser, testRealmSAMLPostLoginPage);
|
||||||
|
|
||||||
|
@ -331,9 +340,13 @@ public abstract class AbstractSAMLServletsAdapterTest extends AbstractServletsAd
|
||||||
salesPostPassiveServletPage.logout();
|
salesPostPassiveServletPage.logout();
|
||||||
salesPostPassiveServletPage.navigateTo();
|
salesPostPassiveServletPage.navigateTo();
|
||||||
|
|
||||||
waitUntilElement(By.xpath("//body")).text().not().contains("principal=");
|
if (forbiddenIfNotAuthenticated) {
|
||||||
//Different 403 status page on EAP and Wildfly
|
waitUntilElement(By.xpath("//body")).text().not().contains("principal=");
|
||||||
assertTrue(driver.getPageSource().contains("Forbidden") || driver.getPageSource().contains("<body></body>") || driver.getPageSource().equals(""));
|
//Different 403 status page on EAP and Wildfly
|
||||||
|
assertTrue(driver.getPageSource().contains("Forbidden") || driver.getPageSource().contains("<body></body>") || driver.getPageSource().equals(""));
|
||||||
|
} else {
|
||||||
|
waitUntilElement(By.xpath("//body")).text().contains("principal=null");
|
||||||
|
}
|
||||||
assertForbiddenLogin(salesPostServletPage, "unauthorized", "password", testRealmSAMLPostLoginPage);
|
assertForbiddenLogin(salesPostServletPage, "unauthorized", "password", testRealmSAMLPostLoginPage);
|
||||||
assertForbidden(salesPostPassiveServletPage);
|
assertForbidden(salesPostPassiveServletPage);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<module name="org.codehaus.jackson.jackson-mapper-asl" />
|
<module name="org.codehaus.jackson.jackson-mapper-asl" />
|
||||||
<module name="org.bouncycastle" />
|
<module name="org.bouncycastle" />
|
||||||
<module name="org.jboss.xnio" />
|
<module name="org.jboss.xnio" />
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</deployment>
|
</deployment>
|
||||||
</jboss-deployment-structure>
|
</jboss-deployment-structure>
|
|
@ -23,13 +23,8 @@
|
||||||
|
|
||||||
<module-name>%CONTEXT_PATH%</module-name>
|
<module-name>%CONTEXT_PATH%</module-name>
|
||||||
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>Servlet</servlet-name>
|
|
||||||
<servlet-class>org.keycloak.testsuite.adapter.servlet.SendUsernameServlet</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
|
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
<servlet-name>Servlet</servlet-name>
|
<servlet-name>javax.ws.rs.core.Application</servlet-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.keycloak.testsuite.adapter;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractSAMLFilterServletAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.UseServletFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
@AppServerContainer("app-server-eap")
|
||||||
|
public class EAPSAMLFilterAdapterTest extends AbstractSAMLFilterServletAdapterTest {
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.keycloak.testsuite.adapter;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractSAMLFilterServletAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.UseServletFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
@AppServerContainer("app-server-eap6")
|
||||||
|
public class EAPSAMLFilterAdapterTest extends AbstractSAMLFilterServletAdapterTest {
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.keycloak.testsuite.adapter;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractSAMLFilterServletAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
@AppServerContainer("app-server-wildfly")
|
||||||
|
public class WildflySAMLFilterAdapterTest extends AbstractSAMLFilterServletAdapterTest {
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package org.keycloak.testsuite.adapter;
|
||||||
|
|
||||||
|
import org.keycloak.testsuite.adapter.servlet.AbstractSAMLFilterServletAdapterTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AppServerContainer;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.UseServletFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author mhajas
|
||||||
|
*/
|
||||||
|
@AppServerContainer("app-server-wildfly9")
|
||||||
|
public class Wildfly9SAMLFilterAdapterTest extends AbstractSAMLFilterServletAdapterTest {
|
||||||
|
}
|
|
@ -173,6 +173,7 @@
|
||||||
<browser>${browser}</browser>
|
<browser>${browser}</browser>
|
||||||
<firefox_binary>${firefox_binary}</firefox_binary>
|
<firefox_binary>${firefox_binary}</firefox_binary>
|
||||||
|
|
||||||
|
<project.version>${project.version}</project.version>
|
||||||
</systemPropertyVariables>
|
</systemPropertyVariables>
|
||||||
<properties>
|
<properties>
|
||||||
<property>
|
<property>
|
||||||
|
|
Loading…
Reference in a new issue