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>
© Ceptor ApS. All Rights Reserved.