Install IG in Jetty

Configure Jetty to use the same protocol as the application you are protecting with IG. If the protected application is on a remote system, configure Jetty to use the same port as the protected application. If the protected application listens on both an HTTP and an HTTPS port, configure Jetty to listen on both an HTTP and an HTTPS port.

To configure Jetty to use an HTTP port other than 8080, modify the defaults in /path/to/jetty/etc/jetty.xml. Search for the default value of 8080 and replace it with the new port number.

IG depends on javax.websocket-api version 1.1, which is a higher version than that provided by Jetty. To prevent errors related to WebSocket, do not include the websocket configuration modules when you configure Jetty.

To change the default port for Jetty in HTTP, edit http.ini.

To change the default port for Jetty in HTTPS, edit server.ini.

Downloading and Starting IG in Jetty

The commands in this guide assume that you install Jetty to /path/to/jetty, and after installation, you have a directory /path/to/jetty/webapps in which you install IG. If you use another directory structure, substitute the commands.

  1. Download a supported version of Jetty server from its download page, and install it to /path/to/jetty.

  2. Download IG-7.1.0.war from the ForgeRock BackStage download site.

  3. Copy the .war file:

    $ cp IG-7.1.0.war /path/to/jetty/webapps/IG-7.1.0.war

    Jetty automatically deploys IG in the root context on startup.

  4. Start Jetty:

    • To start Jetty in the background, enter:

      $ /path/to/jetty/bin/jetty.sh start
    • To start Jetty in the foreground, enter:

      $ cd /path/to/jetty/
      $ java -jar start.jar
  5. Check that IG is running in one of the following ways:

To use IG for multiple protected applications running on different hosts, set a cookie domain as follows:

  • For stateful sessions, add a session domain handler element that specifies the domain to /path/to/jetty/etc/webdefault.xml, as in the following example:

    <context-param>
      <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
      <param-value>.example.com</param-value>
    </context-param>

    Restart Jetty to read the configuration changes.

    If JwtSession is not configured, stateful sessions are created automatically. For more information, see Sessions.

  • For stateless sessions, configure the domain property of JwtSession. When set, the JWT cookie can be accessed from different hosts in that domain. When not set, the JWT cookie can be accessed only from the host where the cookie was created. For information, see JwtSession.

Configure IG for HTTPS (Server-Side) in Jetty

This section describes how to set up Jetty to run IG over HTTPS. For information about the set up for HTTPS (client-side), see Configure IG For HTTPS (Client-Side).

These instructions are for Jetty 9.4.21, and are not compatible with earlier versions of Jetty. For more information about Jetty and HTTPS, see http://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory.

  1. Install Jetty, and set up the location for the Jetty distribution binaries:

    • Download a supported version of Jetty server from its download page, and install it to /path/to/jetty.

    • Set the environment variable JETTY_HOME for /path/to/jetty:

      $ export JETTY_HOME=/path/to/jetty
  2. Set up the location for configurations and customizations to the Jetty distribution:

    • Create a directory /path/to/jetty_base.

    • Set the environment variable JETTY_BASE for /path/to/jetty_base:

      $ export JETTY_BASE=/path/to/jetty_base
  3. Set up the keystore:

    • Remove the built-in keystore:

      $ rm $JETTY_HOME/modules/ssl/keystore
    • Generate a key pair with a self-signed certificate in the keystore:

      $ keytool \
      -genkey \
      -alias jetty \
      -keyalg RSA \
      -keystore $JETTY_HOME/modules/ssl/keystore \
      -storepass password \
      -keypass password \
      -dname "CN=openig.example.com,O=Example Corp,C=FR"

      Because KeyStore converts all characters in its key aliases to lower case, use only lowercase in alias definitions of a KeyStore.

  4. Create a directory to store local server customization and configurations in $JETTY_BASE:

    • Delete the global start.ini:

      $ rm $JETTY_HOME/start.ini
    • From $JETTY_BASE, create the start.d folder to hold the module .ini files:

      $ cd $JETTY_BASE
      $ java -jar $JETTY_HOME/start.jar --create-startd
      
      MKDIR : ${jetty.base}/start.d
      INFO  : Base directory was modified
  5. From $JETTY_BASE, add the following Jetty configuration modules:

    $ cd $JETTY_BASE
    $ java  -jar $JETTY_HOME/start.jar \
    --add-to-start=server,webapp,deploy,ssl,jstl,ext,jsp,resources,console-capture,http,https
    
    INFO  : webapp          initialized in ${jetty.base}/start.d/webapp.ini
    INFO  : ext             initialized in ${jetty.base}/start.d/ext.ini
    INFO  : server          initialized in ${jetty.base}/start.d/server.ini
    INFO  : mail            transitively enabled
    INFO  : servlet         transitively enabled
    INFO  : jsp             initialized in ${jetty.base}/start.d/jsp.ini
    INFO  : annotations     transitively enabled
    INFO  : resources       initialized in ${jetty.base}/start.d/resources.ini
    INFO  : transactions    transitively enabled
    INFO  : threadpool      transitively enabled, ini template available with --add-to-start=threadpool
    INFO  : ssl             initialized in ${jetty.base}/start.d/ssl.ini
    INFO  : plus            transitively enabled
    INFO  : deploy          initialized in ${jetty.base}/start.d/deploy.ini
    INFO  : jstl            initialized in ${jetty.base}/start.d/jstl.ini
    INFO  : security        transitively enabled
    INFO  : apache-jsp      transitively enabled
    INFO  : jndi            transitively enabled
    INFO  : console-capture initialized in ${jetty.base}/start.d/console-capture.ini
    INFO  : apache-jstl     transitively enabled
    INFO  : http            initialized in ${jetty.base}/start.d/http.ini
    INFO  : client          transitively enabled
    INFO  : https           initialized in ${jetty.base}/start.d/https.ini
    INFO  : bytebufferpool  transitively enabled, ini template available with --add-to-start=bytebufferpool
    MKDIR : ${jetty.base}/lib
    MKDIR : ${jetty.base}/lib/ext
    MKDIR : ${jetty.base}/resources
    MKDIR : ${jetty.base}/etc
    COPY  : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
    MKDIR : ${jetty.base}/webapps
    MKDIR : ${jetty.base}/logs
    INFO  : Base directory was modified

    IG depends on javax.websocket-api version 1.1, which is a higher version than that provided by Jetty. To prevent errors related to WebSocket, do not include the websocket configuration modules when you configure Jetty.

    To change the default port for Jetty in HTTP, edit http.ini.

    To change the default port for Jetty in HTTPS, edit server.ini.

  6. Replace jetty-util-*.jar with the version for your installation, and find the obfuscated form of the keystore password:

    $ cd $JETTY_HOME/lib
    $ ls jetty-util-*.jar
    $ java -cp jetty-util-.jar org.eclipse.jetty.util.security.Password password*
    
    password
    OBF:1v2...v1v
    MD5:5f4...f99
  7. In $JETTY_BASE/start.d/ssl.ini, uncomment the following lines, and update the passwords with the OBF password returned in the previous step:

    ## Connector port to listen on
    jetty.ssl.port=8443
    
    ## Keystore file path (relative to $jetty.base)
    jetty.sslContext.keyStorePath=etc/keystore
    
    ## Keystore password
    jetty.sslContext.keyStorePassword=OBF:1v2j1uum1xtv1zej1zer1xtn1uvk1v1v
    
    ## KeyManager password
    jetty.sslContext.keyManagerPassword=OBF:1v2j1uum1xtv1zej1zer1xtn1uvk1v1v
  8. Copy the IG .war file to $JETTY_BASE/webapps/IG-7.1.0.war.

  9. Go to $JETTY_BASE, and start Jetty:

    $ cd $JETTY_BASE
    $ java -jar $JETTY_HOME/start.jar
  10. Access the IG welcome page on https://openig.example.com:8443.

    If you see warnings that the site is not secure, or that the self-signed certificate is not valid, respond to the warnings to access the site.

Configure Access MySQL Over JNDI in Jetty

If IG accesses an SQL database, then you must configure Jetty to access the database over JNDI. To do so, you must add the driver .jar for the database, set up a JNDI data source, and set up a reference to that data source.

The following steps are for MySQL Connector/J:

  1. Download the MySQL JDBC Driver Connector/J from http://dev.mysql.com/downloads/connector/j.

  2. Copy the driver .jar to /path/to/jetty/lib/jndi/ so that it is on Jetty’s class path.

  3. Add a JNDI data source for your MySQL server and database in /path/to/jetty/etc/jetty.xml:

    <New id="jdbc/forgerock" class="org.eclipse.jetty.plus.jndi.Resource">
      <Arg></Arg>
      <Arg>jdbc/forgerock</Arg>
      <Arg>
        <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
          <Set name="Url">jdbc:mysql://localhost:3306/databasename</Set>
          <Set name="User">mysqladmin</Set>
          <Set name="Password">password</Set>
        </New>
      </Arg>
    </New>
  4. Add a resource reference to the data source in /path/to/jetty/etc/webdefault.xml:

    <resource-ref>
        <description>MySQL Connection</description>
        <res-ref-name>jdbc/forgerock</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
  5. Restart Jetty to read the configuration changes.

About Session Stickiness and Session Replication for Jetty

Jetty has provisions for session stickiness, and also for session replication through clustering:

  • Jetty’s persistent session mechanism appends a node ID to the session ID in the same way Tomcat appends the jvmRoute value to the session cookie. This can be useful for session stickiness if your load balancer examines the session ID.

  • Session Clustering with a Database describes how to configure Jetty to persist sessions over JDBC, allowing session replication.

    Unless it is set up to be highly available, the database can be a single point of failure in this case.

  • Session Clustering with MongoDB describes how to configure Jetty to persist sessions in MongoDB, allowing session replication.

    The Jetty documentation recommends this implementation when session data is seldom written, but often read.