Integrating with Jetty
Integration with Jetty can be done in a number of ways.
Integrating with Jetty in Ceptors Distribution
Ceptor contains a built-in Jetty server, which you can use for your own webapps.
Here is a sample launcher xml that starts a demoapp
pp_launch_demoapp.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Ceptor Launcher configuration -->
<ceptorlauncher port="21311"
launcherclasspath="classes/launcher;lib/CeptorAgent.jar;extlib/logback-core-1.1.5.jar;extlib/logback-classic-1.1.5.jar;extlib/slf4j-api-1.7.16.jar" jvmstartdelay="10">
<!-- Ceptor DemoApp -->
<jvm name="demoapp" vmargs="-Xmx1024M -Xnoclassgc" systemclasspath="">
<config servers="nios://localhost:21233?validateservercert=false" />
<classloader name="demoapp" extraclasspath="extlib_extras/jsp">
<service name="webserver1" launcherclass="dk.itp.managed.service.GenericWarLauncher">
<property name="registerppsecurityhandler" value="true"/>
<webserver webapp="${portalprotect.home}/samples/demoapp/PortalProtectDemoApp.war"
contextpath="/"
bindaddress="0.0.0.0" httpport="8080" sslport="0" minthreads="2" maxthreads="500"
maxpostsize="67108864" maxidletime="10000"
responseheadersize="32768"
outputbuffersize="32768"
/>
</service>
</classloader>
</jvm>
</ceptorlauncher>In the above example, the property
<property name="registerppsecurityhandler" value="true"/>is all that is required to register the security handler.
Programmatically Install Jetty Security Handler
You can also install the Jetty Security Handler programmatically - Here is a full example, which sets up a security handler, and launches and embedded Jetty Server:
package dk.portalprotect.launcher.demoapp;
import java.io.File;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.security.auth.Subject;
import javax.servlet.ServletRequest;
import dk.itp.security.passticket.Agent;
import dk.itp.security.passticket.PTException;
import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.SimpleInstanceManager;
import org.eclipse.jetty.apache.jsp.JettyJasperInitializer;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.security.DefaultIdentityService;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* Bootstrapper, used to start the demoapp using an embedded jetty webserver
*/
public class StartJetty {
public static class PPPrincipal implements Principal {
String sessionid;
public PPPrincipal(String sessionid) {
this.sessionid = sessionid;
}
public String getName() {
return sessionid;
}
}
public static class PPUserIdentity implements UserIdentity {
Subject subject;
PPPrincipal principal;
public PPUserIdentity(Subject subject, PPPrincipal principal) {
this.subject = subject;
this.principal = principal;
}
public Subject getSubject() {
return subject;
}
public Principal getUserPrincipal() {
return principal;
}
public boolean isUserInRole(String role, Scope scope) {
try {
boolean member = Agent.getInstance().isMemberOfGroup(principal.sessionid, role);
if (!member) {
System.err.println("Warning: User: "+ principal.sessionid + " was not a member of role: " + role);
}
return member;
} catch (PTException e) {
e.printStackTrace();
return false;
}
}
}
public static class PPLoginService implements LoginService {
IdentityService identService = new DefaultIdentityService();
public UserIdentity login(String user, Object credentials, ServletRequest request) {
if (Agent.getInstance().isValid(user)) {
PPPrincipal principal = new PPPrincipal(user);
Subject subject = new Subject();
subject.getPrincipals().add(principal);
return new PPUserIdentity(subject, principal);
}
return null;
}
public boolean validate(UserIdentity useridentity) {
if (useridentity instanceof PPUserIdentity) {
return Agent.getInstance().isValid(((PPUserIdentity)useridentity).principal.sessionid);
}
return false;
}
public void setIdentityService(IdentityService identityservice) {
identService = identityservice;
}
public String getName() {
return "PortalProtect Security Realm";
}
public IdentityService getIdentityService() {
return identService;
}
public void logout(UserIdentity useridentity) {
if (useridentity instanceof PPUserIdentity) {
try {
Agent.getInstance().logoff(((PPUserIdentity)useridentity).principal.sessionid);
} catch (PTException e) {
}
}
}
}
private static List<ContainerInitializer> jspInitializers()
{
JettyJasperInitializer sci = new JettyJasperInitializer();
ContainerInitializer initializer = new ContainerInitializer(sci, null);
List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>();
initializers.add(initializer);
return initializers;
}
public static void main(String[] arguments) {
try {
System.setProperty("org.apache.jasper.compiler.disablejsr199","false");
boolean develop = false;
int port = 8080;
for(int i = 0; i < arguments.length; i++) {
if (arguments[i].equals("-develop"))
develop = true;
else if (arguments[i].equals("-port") && i+1 < arguments.length) {
port = Integer.parseInt(arguments[++i]);
}
}
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.setSendServerVersion(false);
httpConfig.setSendXPoweredBy(false);
httpConfig.setSendDateHeader(false);
httpConfig.setResponseHeaderSize(32768);
httpConfig.setOutputBufferSize(32768);
final Server srv = new Server();
ServerConnector con = new ServerConnector(srv, new HttpConnectionFactory(httpConfig));
con.setPort(port);
srv.setConnectors(new Connector[] {con});
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setAttribute("org.eclipse.jetty.containerInitializers", jspInitializers());
webapp.setAttribute(InstanceManager.class.getName(), new SimpleInstanceManager());
if (develop) {
webapp.setWar("webapp");
} else {
if (new File("dist/PortalProtectDemoApp.war").exists())
webapp.setWar("dist/PortalProtectDemoApp.war");
else
webapp.setWar("PortalProtectDemoApp.war");
}
webapp.getSecurityHandler().setLoginService(new PPLoginService());
webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(60*60);
srv.setHandler(webapp);
srv.start();
Handler handler = srv.getHandler();
if(handler instanceof WebAppContext) {
webapp.getSessionHandler().getSessionManager().setMaxInactiveInterval(60*60); // sets to 30 sec
}
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
try {
srv.stop();
} catch(Throwable t) {
System.err.println(new Date() + ": Problem shutting down.");
t.printStackTrace();
}
}
}));
System.out.println("Jetty now ready on port " + port + " - connect to the demoapp using the PP dispatcher.");
while(true)
Thread.sleep(60000);
} catch (Throwable e) {
System.err.println("Fatal error starting webserver");
e.printStackTrace();
}
}
}
Adding a Security Handler in a Webapp
If you wish, you can also add a security handler directly within your .war file without starting up Jetty yourself.
Simply add a class like this:
Sample Jetty LoginService
package io.ceptor.jetty;
import java.security.Principal;
import javax.security.auth.Subject;
import javax.servlet.ServletRequest;
import org.eclipse.jetty.security.DefaultIdentityService;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.server.UserIdentity;
import dk.itp.security.passticket.Agent;
import dk.itp.security.passticket.PTException;
/**
* Ceptor Jetty Login Service
*/
public class LoginService implements org.eclipse.jetty.security.LoginService {
public static class PPPrincipal implements Principal {
String sessionid;
public PPPrincipal(String sessionid) {
this.sessionid = sessionid;
}
public String getName() {
return sessionid;
}
}
public static class PPUserIdentity implements UserIdentity {
Subject subject;
PPPrincipal principal;
public PPUserIdentity(Subject subject, PPPrincipal principal) {
this.subject = subject;
this.principal = principal;
}
public Subject getSubject() {
return subject;
}
public Principal getUserPrincipal() {
return principal;
}
public boolean isUserInRole(String role, Scope scope) {
try {
boolean member = Agent.getInstance().isMemberOfGroup(principal.sessionid, role);
if (!member) {
// System.err.println("Warning: User: " + principal.sessionid + " was not a member of role: " + role);
}
return member;
} catch (PTException e) {
// e.printStackTrace();
return false;
}
}
}
IdentityService identService = new DefaultIdentityService();
public UserIdentity login(String username, Object credentials) {
return login(username, credentials, null);
}
public UserIdentity login(String user, Object credentials, ServletRequest request) {
if (Agent.getInstance().isValid(user)) {
PPPrincipal principal = new PPPrincipal(user);
Subject subject = new Subject();
subject.getPrincipals().add(principal);
return new PPUserIdentity(subject, principal);
}
return null;
}
public boolean validate(UserIdentity useridentity) {
if (useridentity instanceof PPUserIdentity) {
return Agent.getInstance().isValid(((PPUserIdentity) useridentity).principal.sessionid);
}
return false;
}
public void setIdentityService(IdentityService identityservice) {
identService = identityservice;
}
public String getName() {
return "Ceptor Security Realm";
}
public IdentityService getIdentityService() {
return identService;
}
public void logout(UserIdentity useridentity) {
if (useridentity instanceof PPUserIdentity) {
try {
Agent.getInstance().logoff(((PPUserIdentity) useridentity).principal.sessionid);
} catch (PTException e) {
}
}
}
}
And then create the following jetty-web.xml in your WEB-INF folder:
Sample jetty-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty/Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="securityHandler">
<Set name="loginService"><New class="io.ceptor.jetty.LoginService"></New></Set>
</Get>
</Configure>