How to use JASPI/JASPIC on Jetty? - java

On Jetty's main project page compatibility with JASPI (JASPIC/JSR 196) is mentioned.
However, the distribution of Jetty 8 does not seem to contain any classes related to JASPI. There's a jetty-security-8.1.8.v20121106.jar jar in [jetty home]/lib, but this one does not contain any of the JASPIC/JASPI types.
The documentation about JASPIC/JASPI on the Jetty wiki is only a placeholder and does not contain any information.
After some Googling I found JavaDocs on the Eclipse site and discovered there should be a jetty-jaspi-8.1.8.v20121106.jar somewhere. Those JavaDocs are included in the distribution as well. Finally, a jetty-jaspi repo appears at Github.
Obviously there is some amount of support available, but why are those classes seemingly not present in the Jetty distribution and where is the documentation on how to configure this? What am I missing?

This project (https://github.com/guofengzh/jaspi-on-jetty) is a working example of the JASPI API in jetty that uses geronimo-jaspi which in turn calls back to the jetty-jaspi modules for the authentication. Geronimo seems to be providing the configuration mechanism and jetty the authentication modules themselves in this example.
It seems as though you can select a form, digest or basic authentication methods. A quick test of the form based login has shown it appears to function.
The Jaspi authentication factory is setup in jetty-web.xml like so:
<Set name="securityHandler">
<New class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<Set name="loginService">
<New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
<Set name="name">JAASRealm</Set>
<Set name="loginModuleName">jaas</Set>
</New>
</Set>
<Set name="authenticatorFactory">
<New class="org.eclipse.jetty.security.jaspi.JaspiAuthenticatorFactory" />
</Set>
</New>
</Set>
And the jaspi configuration file is referenced via a system property in the pom.xml file:
<systemProperty>
<name>org.apache.geronimo.jaspic.configurationFile</name>
<value>./conf/jaspi/form-test-jaspi-2.xml</value>
</systemProperty>
Additionally, the jaspi library you mentioned is added as a dependency in the pom, along with the geronimo jaspi implementation:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaspi</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.components</groupId>
<artifactId>geronimo-jaspi</artifactId>
<version>2.0.0</version>
</dependency>
I have also been unable to find documenation on the topic. It seems as though the jetty-jaspi module is not one of the standard start options, but could be added to the ${jetty.home/lib/ext} directory (see Jetty classloading).

Related

How can I make application use both SSL and TLS

Our java application presently uses SSL for communication between client and server using https. Customer requested if an upgrade can be done to TLS and if they can use both TLS and SSL at different locations. I cant understand clearly how to answer their questions or how to proceed.
jetty-ssl.xml file is as follows :
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<!-- =============================================================== -->
<!-- Configure SSL for the Jetty Server -->
<!-- this configuration file should be used in combination with -->
<!-- other configuration files. e.g. -->
<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
<!-- =============================================================== -->
<Configure id="Server" class="org.mortbay.jetty.Server">
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.security.SslSocketConnector">
<Set name="Port">8443</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="handshakeTimeout">2000</Set>
<Set name="keystore">/xservices-config/keystore</Set>
<Set name="password">password</Set>
<Set name="keyPassword">password</Set>
<Set name="truststore">/keystore</Set>
<Set name="trustPassword">password</Set>
<Set name="handshakeTimeout">2000</Set>
<!-- Set name="ThreadPool">
<New class="org.mortbay.thread.BoundedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">250</Set>
</New>
</Set -->
</New>
</Arg>
</Call>
</Configure>
Please let me know how to implement it.
Are you sure you need to "enable" this? I just went back at the jetty documentation and figured, as long as you don't exclude a protocol, you're allowing them all. Check your installation either with a local tool (sslscan, nmap, etc.) or a web application (e.g. from Qualys or COMODO).
If you find with the above analysis that you don't have the versions running, you could use an Apache webserver as HTTPS end-point and mod_proxy the content to jetty.
If that above is your SSL configuration for jetty, I strongly recommend you to harden it! Exclude legacy SSL protocols (e.g. SSLv2) and weak ciphers! As others have mentioned SSLv3 is actually legacy as well and not recommended anymore. In your position, I would get back to your client and check why he wants to have SSLv3 running. Unless he isn't expecting connections from dead old systems (e.g. Win XP with IE), there is not much of a reason to have SSLv3 running. However, if he does not know who is connecting to his page with what browsers, have a look at the logs. If the logs don't show an indication of the web browser used to connect to the application, I strongly recommend to enable it, run it for a period and then take a decision.

Java SQL DataSource Resource Configuration

In Java Spring, I am trying to keep my database settings outside of the main app so that it can be configured on other servers with minimal effort. I am using Tomcat 7 for my production server and a Jetty server (jetty-maven-plugin version 8.1.14.v20131031) for development.
The main problem I am running into is I cannot get the working Tomcat 7 configuration to translate to Jetty using the same class (javax.sql.DataSource). I am starting with this class, opposed to a more robust one so that I am starting with something as basic as possible.
If this is a case where there is no direct translation between the two servers, or this is simply bad practice I am looking for what would be a good practice or standard.
For example, this answer is an alternative configuration that uses a different class, and works with Jetty. (However it doesn't answer why the basic DataSource class works with Tomcat and not with Jetty.)
I have the a Resource entry in server.xml like so:
<Context path="/" docBase="/var/lib/tomcat7/webapps/myapp" reloadable="true">
<Resource name="mysql-dataSource" auth="Container" type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/dbname"
username="dbuser"
password="dbuser" />
</Context>
jetty-maven-plugin POM entry:
...
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.14.v20131031</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
</dependencies>
<configuration>
<!-- <useProvidedScope>?</useProvidedScope> -->
<webApp>
<jettyEnvXml>${basedir}/jetty-env.xml</jettyEnvXml>
</webApp>
</configuration>
</plugin>
...
This works fine in Tomcat7.
For Jetty, I am using jetty-env.xml with the following configuration:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.eclipse.org/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.webapp.WebAppContext">
<New id="ds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>mysql-dataSource</Arg>
<Arg>
<New class="javax.sql.DataSource">
<Set name="driverClassName">com.mysql.jdbc.Driver</Set>
<Set name="url">jdbc:mysql://localhost:3306/dbname</Set>
<Set name="username">dbuser</Set>
<Set name="password">dbuser</Set>
</New>
</Arg>
</New>
</Configure>
With that I get this error:
java.lang.IllegalStateException: No Constructor: <New class="javax.sql.DataSource">...
Add this
<Arg></Arg>
above
<Arg>mysql-dataSource</Arg>
As first "Arg" is the scope, and without it, the rest of your arguments are out of position, and are probably causing your issue.
For more information Jetty/Howto/Configure JNDI Datasource
Edit :
Have you add scope provided for the specific version of Jetty ?

How to configure Jetty to reload a WebAppContext when classes are changed

I'm developing a web application and I run Jetty as the development and testing environment when I develop under Eclipse.
When I make changes to Java classes, Eclipse automatically compiles them to the build directory, but Jetty won't see the changes until I stop and start the server. I know that Jetty supports "hot deployment" using ContextDeployer that will refresh updated application contexts, but it relies on a context file in a context directory being updated - which is not very useful in my case.
Is there a way to set up Jetty so that it will reload the web app when any of the classes it uses is updated?
My current jetty.xml looks something like this:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Set name="ThreadPool"><!-- bla bla --></Set>
<Call name="addConnector"><!-- bla bla --></Call>
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="webapp" class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="displayName">My Web App</Set>
<Set name="resourceBase">src/main/webapp</Set>
<Set name="descriptor">src/main/webapp/WEB-INF/web.xml</Set>
<Set name="contextPath">/mywebapp</Set>
</New>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
</Configure>
We have not found a way of doing this (aside from implementing our own version of the org.eclipse.jetty.deploy.providers.WebAppProvider).
We have configured jetty to hot deploy webapps from the webapps folder (property monitoredDirName of the WebappDeployer).
Then to hot deploy, I recreate my link in this folder to the src/main/webapp folder of my Eclipse project. The linked must be suffixed .war.
Not really automatic but good enough and avoids a Jetty restart.
If you go the route of re-implementing a WebappDeployer, I would not monitor the changes in .class files - they change too much when compiled by Eclipse, particularly in the case of automatic builds. I would implement a 'Tomcat like' solution by monitoring changes to the web.xml file. Then a dummy change saved to this file from Eclipse would trigger a redeployment.
It is also possible to configure your jetty app with maven and starting periodical builds with Jenkins (even every couple of seconds, depending on the maschine you are working on)

Jetty Classloading issue

I'm using the jetty maven plugin to run a webapp locally and I'm getting a class cast exception when I try to pull in a JNDI resource.
I have a jetty config with a resource object, which is a configuration bean that is utilized via JNDI. This class resides in a different jar on the classpath that is in the lib directory:
<Configure class="org.mortbay.jetty.Server">
<New class="org.mortbay.jetty.plus.naming.Resource">
<Arg>config/MyConfigObject</Arg>
<Arg>
<New class="my.config.ConfigObject">
<Set name="foo">bar</Set>
</New>
</Arg>
</New>
</Configure>
This is retrieved via Spring:
<bean id="MyConfigObject" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/config/MyConfigObject" />
</bean>
Inside of a servlet, I'm grabbing the object manually:
final MyConfigObject config = (MyConfigObject) applicationContext.getBean("MyConfigObject");
But when I try to access the servlet, I get:
java.lang.ClassCastException: my.config.MyConfigObject cannot be cast to my.config.MyConfigObject
I'm pretty sure the problem is due to class loading, but I'm not 100% certain. MyConfigObject's class loader is the default sun class loader, while the thread's current class loader is jetty's WebAppClassLoader. My jar is in WEB-INF/lib, and I've even added it manually to extraClasspath in the maven plugin configuration:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.25</version>
<configuration>
<jettyConfig>${basedir}/test/jetty.xml</jettyConfig>
<webAppSourceDirectory>${basedir}/target/${project.artifactId}</webAppSourceDirectory>
<webXml>${basedir}/war/WEB-INF/web.xml</webXml>
<webAppConfig>
<extraClasspath>${basedir}/target/${project.artifactId}/WEB-INF/lib/myConfigJar-1.0.jar</extraClasspath>
</webAppConfig>
</configuration>
<dependencies>
<dependency>
<groupId>testing</groupId>
<artifactId>myConfigJar</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
I'm kind of stuck at this point. Does anyone know how to resolve this?
The problem is that you've got the jar listed in too many places - you attempts to add it to extraClasspath will actually make it worse, not better.
You say it's in WEB-INF/lib, but I assume it's also listed as a dependency in your pom.xml
You don't want to do that, you need to have 1 single reference to it. Either as a dependency in your pom.xml or in your lib directory, or in extraClasspath, but only in 1 place.
(Hint: pom.xml is almost certainly the right place, get rid of the others)
your webapp should not include the "my.config.MyConfigObject" class (and related classes) in it.
the underlying problem is that you are getting the class loaded by 2 different classloaders. you need to eliminate the class from your webapp classloader so that your webapp will use the same class that jetty is using.

Jetty ant task configuration

Two questions on configuring the jetty ant task
to get jetty to listen on a different port, I'm doing this in the jetty.xml:
<Call name="addConnector">
<Arg>
<New class="org.mortbay.jetty.nio.SelectChannelConnector">
<Set name="port"><SystemProperty name="jetty.port" default="9080"/></Set>
</New>
</Arg>
</Call>
and referencing this in the ant script, e.g.
<jetty tempDirectory="..." jettyXml="...jetty.xml">
Unfortunately this simply gets jetty to load both 9080 and 8080. How do I get jetty to not require 8080?
Second question - does the jetty task support forking the jetty process, or do I have to do that with a direct ant exec instead of using the jetty plugin?
Nevermind. For anyone stuck with the same issue, it can be solved like this:
<jetty tempDirectory="...">
<connectors>
<selectChannelConnector port="9999" />
</connectors>
</jetty>
The jetty.xml is removed, calling that adds the referenced port rather than replacing. Similar to the syntax
< systemProperties>
<systemProperty name="jetty.port" value="9181"/>
</systemProperties>
which replaces the port referenced in the jetty xml but adds to instead of overwriting the default port.

Categories