Skip to content

Instantly share code, notes, and snippets.

@digulla
Last active April 29, 2016 01:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save digulla/5c0d80bccde266f7fe84c0529379044d to your computer and use it in GitHub Desktop.
Save digulla/5c0d80bccde266f7fe84c0529379044d to your computer and use it in GitHub Desktop.
Make ZK play nice with Fediz SSO
<!-- Just the dependencies -->
<dependencies>
<dependency>
<groupId>org.apache.cxf.fediz</groupId>
<artifactId>fediz-tomcat8</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat8.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<zk>
<!--... more stuff...-->
<!-- When ZkAwareFederationAuthenticator denies the request, reload the whole app -->
<client-config>
<error-reload>
<device-type>ajax</device-type>
<connection-type>au</connection-type>
<error-code>401</error-code>
<!-- Can't redirect to any app page/servlet/whatever since IDP would block that request. -->
<!-- <reload-uri>/timeout.zul</reload-uri> -->
<reload-uri>/</reload-uri>
</error-reload>
</client-config>
</zk>
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.authenticator.FormAuthenticator;
import org.apache.catalina.connector.Request;
import org.apache.cxf.fediz.core.config.FedizContext;
import org.apache.cxf.fediz.tomcat8.FederationAuthenticator;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
public class ZkAwareFederationAuthenticator extends FederationAuthenticator {
private static final Log log = LogFactory.getLog(FormAuthenticator.class);
@Override
protected synchronized void startInternal() throws LifecycleException {
super.startInternal();
log.info("Started");
}
@Override
protected void redirectToIdp(Request request, HttpServletResponse response, FedizContext fedCtx) throws IOException {
String contextName = request.getServletContext().getContextPath();
if (contextName == null || contextName.isEmpty()) {
contextName = "/";
}
String zkauPath = contextName + "/zkau";
// log.debug("zkauPath: " + zkauPath);
// log.debug("getRequestURL: " + request.getRequest().getRequestURL());
// log.debug("getRequestURI: " + request.getRequest().getRequestURI());
// log.debug("getPathInfo: " + request.getRequest().getPathInfo());
String path = request.getRequest().getRequestURI();
log.info("Request path: [" + path + "]");
if (path.startsWith(zkauPath)) {
log.info("Detected redirect request for /zkau -> deny");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
// Continue with normal request
super.redirectToIdp(request, response, fedCtx);
}
}
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.net.URI;
import java.net.URISyntaxException;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.Context;
import org.apache.catalina.Session;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.connector.Request;
import org.apache.cxf.fediz.core.config.FedizContext;
import org.apache.cxf.fediz.core.config.jaxb.ArgumentType;
import org.apache.cxf.fediz.core.config.jaxb.CallbackType;
import org.apache.cxf.fediz.core.config.jaxb.ContextConfig;
import org.apache.cxf.fediz.core.config.jaxb.FederationProtocolType;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
public class ZkAwareFederationAuthenticatorTest {
@Test
public void testZKAURequest() throws Exception {
Request request = createRequest("/zkau");
ZkAwareFederationAuthenticator tool = new ZkAwareFederationAuthenticator();
FedizContext fedizCtx = createFedizContext();
MockHttpServletResponse response = new MockHttpServletResponse();
tool.redirectToIdp(request, response, fedizCtx);
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
}
@Test
public void testRedirect() throws Exception {
MockTomcatRequest request = createRequest("/");
request.createMockSession();
ZkAwareFederationAuthenticator tool = new ZkAwareFederationAuthenticator();
FedizContext fedizCtx = createFedizContext();
MockHttpServletResponse response = new MockHttpServletResponse();
tool.redirectToIdp(request, response, fedizCtx);
String redirectedUrl = redirectUrlWithoutChangingParts(response);
assertEquals("https://sit-idp-.../rpidp?wa=wsignin1.0&wreply=http%3A%2F%2Flocalhost%2Fabt-poc%2F&wtrealm=http%3A%2F%2Flocalhost%2F&wct=...", redirectedUrl);
}
private String redirectUrlWithoutChangingParts(MockHttpServletResponse response) {
String redirectedUrl = response.getRedirectedUrl();
int pos = redirectedUrl.indexOf("&wct=");
redirectedUrl = redirectedUrl.substring(0, pos) + "&wct=...";
return redirectedUrl;
}
private MockTomcatRequest createRequest(String path) throws URISyntaxException {
MockServletContext servletContext = new MockServletContext("../abt-poc-war/src/main/webapp");
servletContext.setContextPath("/abt-poc");
Connector connector = new Connector();
connector.setParseBodyMethods("POST");
Context tomcatContext = mock(Context.class);
when(tomcatContext.getServletContext()).thenReturn(servletContext);
URI uri = new URI("http://localhost/abt-poc" + path);
org.apache.coyote.Request coyoteRequest = new org.apache.coyote.Request();
coyoteRequest.scheme().setString(uri.getScheme());
coyoteRequest.serverName().setString(uri.getHost());
coyoteRequest.requestURI().setString(uri.getPath());
MockTomcatRequest request = new MockTomcatRequest();
request.setCoyoteRequest(coyoteRequest);
request.setPathInfo("/abt-poc" + path);
request.getMappingData().context = tomcatContext;
request.setConnector(connector);
return request;
}
private static class MockTomcatRequest extends Request {
private Session session;
public void createMockSession() {
session = mock(Session.class);
}
@Override
protected Session doGetSession(boolean create) {
return session;
}
}
private FedizContext createFedizContext() {
FederationProtocolType type = new FederationProtocolType();
CallbackType value = new CallbackType();
value.setType(ArgumentType.STRING);
value.setValue("https://sit-idp-.../rpidp");
type.setIssuer(value);
ContextConfig config = new ContextConfig();
config.setProtocol(type);
FedizContext result = new FedizContext(config);
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment