IllegalStateException: No LoginService for FormAuthenticator Jetty - jetty

I'm configuring a custom JAAS Login module in Jetty.
import org.eclipse.jetty.jaas.spi.AbstractLoginModule;
public class HybridLoginModule extends AbstractLoginModule
I add the file in: jetty-9.4.8/etc/login.conf
hybridRealm {
net.sf.jkniv.jaas.jetty.HybridLoginModule required
}
Enable the jaas in: jetty-9.4.8/start.ini
--module=jaas
jetty.jaas.login.conf=etc/login.conf
And config JAAS JAASLoginService in jetty-9.4.8/etc/jetty-webapp.xml
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="name">Hybrid JAAS Realm</Set>
<Set name="LoginModuleName">hybridRealm</Set>
</New>
</Arg>
</Call>
But when I start jetty server java -jar start.jar the exception is throw
IllegalStateException: No LoginService for FormAuthenticator
java.lang.IllegalStateException: No LoginService for org.eclipse.jetty.security.authentication.FormAuthenticator#25084a1e in org.eclipse.jetty.security.ConstraintSecurityHandler#156b88f5
at org.eclipse.jetty.security.authentication.LoginAuthenticator.setConfiguration(LoginAuthenticator.java:76)
at org.eclipse.jetty.security.authentication.FormAuthenticator.setConfiguration(FormAuthenticator.java:131)

The jetty documentation it's ambiguous, to solution the configuration problem set the realm-name property from web.xml file to same value from <Set name="Name"> proprety, no <Set name="LoginModuleName">.
web.xml file:
<realm-name>xyzREALM</realm-name>
jetty-webapp.xml file:
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="Name">xyzREALM</Set>
<Set name="LoginModuleName">hybridRealm</Set>
</New>

Related

Upgrading to jetty 9.4 replacing the HashSessionManager

After upgrading to jetty 9.4 I notice a ClassNotFoundException for org.eclipse.jetty.server.session.HashSessionManager.
I think I need to use a FileSessionDataStore but I don't see how that is suppose to be set on a SessionHandler.
The configuration I currently have is:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
...
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler">
<Arg>
<New class="org.eclipse.jetty.server.session.HashSessionManager">
<Set name="storeDirectory">my/store/path</Set>
</New>
</Arg>
</New>
</Set>
</Configure>
I don't see what I need to do, SessionHandler doesn't take a SessionDataStore, but a SessionCache can be set on it but it looks like the implementations of SessionCache want a SessionHandler in the constructor, I don't see how to do that in XML.
In the jetty-9.4 session architecture, you have SessionHandler takes a SessionCache, which optionally takes a SessionDataStore.
See OneServletContextWithSession for a programmatic example.
That example uses the NullSessionDataStore, but the principle is the same as the FileSessionDataStore, which is the replacement for the old HashSessionManager ability to store sessions to disk.
The Jetty Documentation contains information on changes from previous versions of Jetty session management to the 9.4 style.
If you follow links in the documentation, you'll also find detailed info on the new session architecture.
As the documentation explains, the easiest way to configure sessions in jetty-9.4 when running in the distribution is to enable the appropriate module. However, if you're running embedded, or you just want to set up session management for a particular webapp in xml, here's some example code of setting up the FileSessionDataStore:
<Get id="sh" name="sessionHandler">
<Set name="sessionCache">
<New class="org.eclipse.jetty.server.session.DefaultSessionCache">
<Arg><Ref id="sh"/></Arg>
<Set name="sessionDataStore">
<New class="org.eclipse.jetty.server.session.FileSessionDataStore">
<Set name="storeDir">/tmp/sessions</Set>
</New>
</Set>
</New>
</Set>
</Get>
Ah I think I worked it out, it is not pretty it ended up as:
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler">
</New>
</Set>
<Call name="getSessionHandler" id="sessionHandler" />
<Ref refid="sessionHandler">
<Set name="SessionCache">
<New class="org.eclipse.jetty.server.session.DefaultSessionCache">
<Arg>
<Ref refid="sessionHandler"/>
</Arg>
<Set name="SessionDataStore">
<New class="org.eclipse.jetty.server.session.FileSessionDataStore">
<Set name="StoreDir">my/store/path</Set>
</New>
</Set>
</New>
</Set>
</Ref>
I followed the easier to read pure java example I found at http://useof.org/java-open-source/org.eclipse.jetty.server.session.FileSessionDataStore
If this doesn't look correct to a Jetty expert I am happy to edit the answer so as not to mislead others.

defining webapp load order in jetty

I have two webapps that might be deployed separately or in the same jetty server. In my situation, one webapp must deploy before the other can complete its deployment, so I'm looking for a solution in the dual deployment case where I can define the deployment order.
I've defined a context xml file with the following:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.server.handler.HandlerList">
<New class="org.eclipse.jetty.server.handler.HandlerList">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/security</Set>
<Set name="war"><SystemProperty name="jetty.home"/>/security_app/war/</Set>
<Call name="addAliasCheck">
<Arg>
<New class="org.eclipse.jetty.server.handler.ContextHandler$ApprovePathPrefixAliases"/>
</Arg>
</Call>
</New>
</Item>
<Item>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="war"><SystemProperty name="jetty.home"/>/main_app/war/</Set>
<Call name="addAliasCheck">
<Arg>
<New class="org.eclipse.jetty.server.handler.ContextHandler$ApprovePathPrefixAliases"/>
</Arg>
</Call>
</New>
</Item>
</Array>
</Set>
</New>
</Configure>
However, with this solution, I get the following error:
java.lang.ClassCastException: org.eclipse.jetty.server.handler.HandlerList cannot be cast to org.eclipse.jetty.server.handler.ContextHandler
at org.eclipse.jetty.deploy.providers.WebAppProvider.createContextHandler(WebAppProvider.java:292)
at org.eclipse.jetty.deploy.App.getContextHandler(App.java:101)
at org.eclipse.jetty.deploy.bindings.StandardDeployer.processBinding(StandardDeployer.java:36)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:186)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:498)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:146)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:605)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:528)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:391)
at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
which of course, is true, though they both are AbstractHandlers in the end. What might I be doing wrong or is there another way to pull this off?
Using Jetty 9.2.1
Thanks
You have hardcoded deployments, don't use the deploy module.
The exception you are getting is the deploy module attempting to find and deploy webapps itself, and is failing to find the org.eclipse.jetty.server.handler.ContextHandler entry it is expecting.
The best way to fix this is to not have separate webapps that depend on each other during deploy/init (that is out of scope for the servlet spec). Make the /main_app/war/ webapp init on demand, not on startup.
Now back to your specific problem ...
Important: do not work / edit / run / configure the ${jetty.home} directory directly.
The ${jetty.base} directory exists for a reason, use it, you'll be much happier when you do.
http://www.eclipse.org/jetty/documentation/current/startup.html
For those things that are load order sensitive, do not use the deploy module with those artifacts. (its safe to use the deploy module for other webapps you have that don't have load order dependencies)
To accomplish this, we'll configure a ${jetty.base} directory to use a custom xml file on startup, along with a /special/ directory for these load order dependent WebAppContexts, making sure that these contexts are not loaded, and managed by the deploy module.
$ cd my-jetty-base
$ mkdir etc
$ gvim etc/special-deploy.xml
$ echo "etc/special-deploy.xml" >> start.ini
$ ls -F
etc/ special/ start.ini webapps
$ ls -F special/
main.war security.war
$ cat start.ini
--module=http
jetty.port=8080
--module=deploy
etc/special-deploy.xml
The special-deploy.xml looks like this ...
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<!-- =============================================================== -->
<!-- Add Load Order Dependant Webapps -->
<!-- =============================================================== -->
<Configure id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
<Call name="addHandler">
<Arg>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/security</Set>
<Set name="war"><SystemProperty name="jetty.base"/>/special/security.war</Set>
<Call name="addAliasCheck">
<Arg>
<New class="org.eclipse.jetty.server.handler.ContextHandler$ApprovePathPrefixAliases"/>
</Arg>
</Call>
</New>
</Arg>
</Call>
<Call name="addHandler">
<Arg>
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/</Set>
<Set name="war"><SystemProperty name="jetty.base"/>/special/main.war</Set>
<Call name="addAliasCheck">
<Arg>
<New class="org.eclipse.jetty.server.handler.ContextHandler$ApprovePathPrefixAliases"/>
</Arg>
</Call>
</New>
</Arg>
</Call>
</Configure>
When you run you'll see the following ...
$ java -jar /path/to/jetty-distribution-9.2.10.v20150310/start.jar
2015-04-29 12:18:55.929:INFO::main: Logging initialized #275ms
2015-04-29 12:18:56.093:WARN:oejsh.ContextHandler:main: ApprovePathPrefixAliases is not safe for production
2015-04-29 12:18:56.094:WARN:oejsh.ContextHandler:main: ApprovePathPrefixAliases is not safe for production
2015-04-29 12:18:56.097:INFO:oejs.Server:main: jetty-9.2.10.v20150310
2015-04-29 12:18:56.150:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /security, did not find org.eclipse.jetty.jsp.JettyJspServlet
2015-04-29 12:18:56.166:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext#751d30f6{/security,file:/tmp/jetty-0.0.0.0-8080-security.war-_security-any-3863723758166154575.dir/webapp/,AVAILABLE}{/home/joakim/examples/load-order-example/special/security.war}
2015-04-29 12:18:56.181:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2015-04-29 12:18:56.183:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext#4f79a28b{/,file:/tmp/jetty-0.0.0.0-8080-main.war-_-any-2704851460101920295.dir/webapp/,AVAILABLE}{/home/joakim/examples/load-order-example/special/main.war}
2015-04-29 12:18:56.184:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/home/joakim/examples/load-order-example/webapps/] at interval 1
2015-04-29 12:18:56.195:INFO:oejs.ServerConnector:main: Started ServerConnector#4ef6d773{HTTP/1.1}{0.0.0.0:8080}
2015-04-29 12:18:56.196:INFO:oejs.Server:main: Started #542ms
^C2015-04-29 12:19:09.594:INFO:oejs.ServerConnector:Thread-0: Stopped ServerConnector#4ef6d773{HTTP/1.1}{0.0.0.0:8080}
2015-04-29 12:19:09.599:INFO:oejsh.ContextHandler:Thread-0: Stopped o.e.j.w.WebAppContext#4f79a28b{/,file:/tmp/jetty-0.0.0.0-8080-main.war-_-any-2704851460101920295.dir/webapp/,UNAVAILABLE}{/home/joakim/examples/load-order-example/special/main.war}
2015-04-29 12:19:09.602:INFO:oejsh.ContextHandler:Thread-0: Stopped o.e.j.w.WebAppContext#751d30f6{/security,file:/tmp/jetty-0.0.0.0-8080-security.war-_security-any-3863723758166154575.dir/webapp/,UNAVAILABLE}{/home/joakim/examples/load-order-example/special/security.war}

Jetty ServletContainerInitialization (SCI ) doesn't call an Initializer provided inside a web-fragment

Here is the scenario,
webapp contains a web.xml
one of the jars contain ServletContainerInitializer
META-INF/services/javax.servlet.ServletContainterInitializer
We are pro grammatically starting jetty, by using XMLConfiguration which is configured with a server object.
XmlConfiguration configuration = new XmlConfiguration(in);
if (type.isInstance(server))
{
configuration.configure(server);
return;
}
boolean success = false;
for (Handler handler : ((Server) server).getHandlers())
{
if (type.isInstance(handler))
{
configuration.configure(handler);
success = true;
}
}
here is the XML file that is used.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Configure class="org.eclipse.jetty.server.Server" id="Server">
<Set name="ThreadPool">
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">2</Set>
<Set name="maxThreads">10</Set>
<Set name="detailedDump">false</Set>
</New>
</Set>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="port">8080</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New class="org.eclipse.jetty.webapp.WebAppContext">
<Arg type="String">src/main/webapp</Arg>
<Arg type="String">/</Arg>
<Set name="extraClasspath">S:/git/projects/p1/target/classes;
S:/maven.repo/org/apache/ahc/1.1.2/ahc-1.1.2.jar;
S:/maven.repo/com/sun/xml/bind/jaxb-xjc/2.2.3.20110115/jaxb-xjc-2.2.3.20110115.jar;
S:/maven.repo/com/springsource/org/hsqldb/1.8.0.10/hsqldb-1.8.0.10.jar;
S:/maven.repo/com/springsource/org/jdom/1.0.0/jdom-1.0.0.jar;
S:/maven.repo/org/apache/mina/1.1.9/mina-1.1.9.jar;
S:/maven.repo/com/springsource/com/mysql/jdbc/5.1.6/jdbc-5.1.6.jar;
</Set>
</New>
</Set>
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
<Set name="dumpAfterStart">false</Set>
<Set name="dumpBeforeStop">false</Set>
</Configure>
When invoked from CLI, jetty DeploymentManager scans the classpath and calls the ServletContainerInitializer provided inside the jar files. What is the equivalent for that to be provided in the XML config file?
When the code is deployed as a war into a jetty installation everything works as expected.
So, that confirms everything is correct.
Nambi,
Here's a link to the jetty documentation page that discusses using annotations in embedded mode: http://www.eclipse.org/jetty/documentation/current/using-annotations-embedded.html
You just need to do the equivalent of the java code in xml - which is always in jetty very straightforward. If you need hints, then have a look at your distro and see what the etc/jetty-annotations.xml file is doing.
Also, if you have annotations inside of jars that are on the extraClasspath, then you need to be using 9.0.6-SNAPSHOT of jetty as I've only just implemented that feature :)
Jan

Empty request logs

I've added this to jetty.xml:
<Get name="handler">
<Call name="addHandler">
<Arg>
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler" />
</Arg>
</Call>
</Get>
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Arg>
/home/aromanov/workspaces/odp-server/ru.focusmedia.odp.server.karaf.launcher/data/jettylog/yyyy_mm_dd.request.log
</Arg>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">true</Set>
<Set name="logServer">true</Set>
<Set name="logDispatch">true</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
The log file is created, but after accessing the page in the browser (and getting "404, powered by Jetty"), nothing appears in the log. Why could this be?
I suspect your handler chain is not configured correctly. Think of the request getting processed by a chain of handlers, and this logging handler is one that just makes a reference to the log file as the request processes through. So if your not getting content in the log then your handler is not in the chain of execution that is occurring. You likely just need to add it to the handler list, before something else that might handle it.

Jetty : Path of Extracted war

I have deployed a .war file inside Jetty Server.
The server has been started, but please tell me where could I see the contents of that war file??
I have read that:
If the extract parameter is true, any packed war or zip files will
first be extracted to a temporary directory before being deployed.
Please tell me where can I set the extract parameter is true and what will be the temporary folder path??
This is my jetty-webapps.xml file
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Ref id="DeploymentManager">
<Call id="webappprovider" name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps</Set>
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
<Set name="scanInterval">1</Set>
<Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
<Set name="extractWars">true</Set>
</New>
</Arg>
</Call>
</Ref>
</Configure>
Check the log file. It should have a like like this
2012-11-06 17:41:54.334:INFO:oejw.WebInfConfiguration:Extract jar:file:/usr/oc/jcast8083/webapps/spdy.war!/ to /tmp/jetty-0.0.0.0-8083-spdy.war-_spdy-any-/webapp
In this case, the content of the war file is in
/tmp/jetty-0.0.0.0-8083-spdy.war-_spdy-any-/webapp
All the war files which you deploy are extracted in Jetty_Home/work for deployment. But if you want that war files should be extracted in temp folder before deployed to work folder, then you can set the extractWars parameter as true in jetty-webapps.xml file. The jetty-webapps.xml file is located in Jetty_HOME/etc/ folder.
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Ref id="DeploymentManager">
<Call id="webappprovider" name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps</Set>
<Set name="defaultsDescriptor"><Property name="jetty.home" default="."/>/etc/webdefault.xml</Set>
<Set name="scanInterval">1</Set>
<Set name="contextXmlDir"><Property name="jetty.home" default="." />/contexts</Set>
<Set name="extractWars">true</Set>
</New>
</Arg>
</Call>
</Ref>
</Configure>
According to this Link:
You have few choices.
1) Specify your own java.io.tmpdir java system property location for jetty to use.
$ java -Djava.io.tmpdir=/path/to/my/new/temp/ -jar start.jar
2) Create a "work" directory under the ${jetty.home} path (whereever that is).
That will cause Jetty to use that work directory instead of whatever the java.io.tmpdir property is set to.
3) Specify the tempDir attribute on the WebAppProvider deployments.
Only valid for war file deployment scenarios, NOT valid for context based deployment.
If you have etc/jetty-webapps.xml in your start.ini you have war file deployments enabled.
Edit the ${jetty.home}/etc/jetty-webapps.xml file and add 1 more attribute on the WebAppProvider.
<Set name="tempDir">/path/to/my/preferred/temp/dir/for/all/webapps</Set>
4) Set the tempDirectory attribute on the WebAppContext with context based deployments.
NOT valid for war file deployment scenarios.
If you have etc/jetty-context.xml in your start.ini you have context based deployments enabled.
Edit the ${jetty.home}/contexts/myapp.xml and add the tempDirectory attribute on the WebAppContext.
<Set name="tempDirectory">/path/to/my/preferred/temp/dir/for/this/context</Set>