JASPI

Enabling this module allows Jetty to utilize authentication modules that implement the Jakarta Authentication (JASPI) specification. JASPI provides an SPI (Service Provider Interface) for pluggable, portable, and standardized authentication modules. Compatible modules are portable between servers that support the JASPI specification. This module provides a bridge from Jakarta Authentication to the Jetty Security framework.

Only modules conforming to the "Servlet Container Profile" with the ServerAuthModule interface within the JakartaAuthentication are supported. These modules must be configured before start-up. Operations for runtime registering or de-registering authentication modules are not supported.

Configuration

The jaspi module

Enable the jaspi module:

# DO NOT EDIT THIS FILE - See: https://jetty.org/docs/

[description]
Enables JASPI authentication for deployed web applications.

[environment]
ee10

[tags]
security

[depend]
ee10-security
auth-config-factory

[ini]
ee10.jakarta.authentication.api.version?=3.0.0

[lib]
lib/jetty-ee10-jaspi-${jetty.version}.jar
lib/ee10-jaspi/jakarta.authentication-api-${ee10.jakarta.authentication.api.version}.jar

[xml]
etc/jaspi/jetty-ee10-jaspi-authmoduleconfig.xml

[files]
basehome:etc/jaspi/jetty-ee10-jaspi-authmoduleconfig.xml|etc/jaspi/jetty-ee10-jaspi-authmoduleconfig.xml

Configure JASPI

Activate either the ee9-jaspi or ee10-jaspi module, whichever matches your EE platform version.

$ java -jar $JETTY_HOME/start.jar --add-modules=ee10-jaspi

You can then register a AuthConfigProvider onto the static AuthConfigFactory obtained with AuthConfigFactory.getFactory(). This registration can be done in the XML configuration file which will be copied to $JETTY_BASE/etc/jaspi/jaspi-authmoduleconfig.xml when the module is enabled.

JASPI Demo

The ee9-jaspi-demo and ee10-jaspi-demo modules illustrate setting up HTTP Basic Authentication using the EE9 and EE 10 Jakarta Authentication modules that come packaged with Jetty.

The following example uses Jetty’s EE 10 implementation of AuthConfigProvider to register a ServerAuthModule directly.

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">

<Configure>
  <Call class="jakarta.security.auth.message.config.AuthConfigFactory" name="getFactory">
    <Call name="registerConfigProvider">

      <!-- The Jetty provided implementation of AuthConfigProvider which will wrap a ServerAuthModule. -->
      <Arg type="String">org.eclipse.jetty.ee10.security.jaspi.provider.JaspiAuthConfigProvider</Arg>

      <!-- A Map of initialization properties. -->
      <Arg>
        <Map>
          <Entry>
            <!-- Provide the fully qualified classname of the ServerAuthModule to be used. -->
            <Item>ServerAuthModule</Item>
            <Item>org.eclipse.jetty.ee10.security.jaspi.modules.BasicAuthenticationAuthModule</Item>
          </Entry>
          <Entry>
            <!-- Realm as utilised by Jetty Security  -->
            <Item>org.eclipse.jetty.ee10.security.jaspi.modules.RealmName</Item>
            <Item>Test Realm</Item>
          </Entry>
        </Map>
      </Arg>

      <!-- Message Layer Identifier as per spec chapter 3.1  -->
      <Arg type="String">HttpServlet</Arg>

      <!-- Application Context Identifier as per spec chapter 3.2

        AppContextID ::= hostname blank context-path
        The algorithm applied here will use the
        _serverName on the configured JaspiAuthenticatorFactory (if set) and try to match it
        against the "server" part (in the "server /test" example below).
        Next it will try to match the ServletContext#getVirtualServerName to the "server" part.
        If neither are set, it will then try to match the first Subject's principal name, and finally fall back to
        the default value "server" if none are available.

        The context-path should match the context path where this applies.
      -->
      <Arg type="String">server /test</Arg>

      <!-- A friendly description of the provided auth-module. -->
      <Arg type="String">A simple provider using HTTP BASIC authentication.</Arg>
    </Call>
  </Call>
</Configure>

Other custom or 3rd party modules that are compatible with the ServerAuthModule interface in JASPI can be registered in the same way.

Integration with Jetty Authentication Mechanisms

To integrate with Jetty authentication mechanisms you must add a LoginService to your context. The LoginService provides a way for you to obtain a UserIdentity from a username and credentials. JASPI can interact with this Jetty LoginService by using the PasswordValidationCallback.

The CallerPrincipalCallback and GroupPrincipalCallback do not require use of a Jetty LoginService. The principal from the CallerPrincipalCallback will be used directly with the IdentityService to produce a UserIdentity.

Replacing the Jetty DefaultAuthConfigFactory

Jetty provides an implementation of the AuthConfigFactory interface which is used to register AuthConfigProviders. This can be replaced by a custom implementation by adding a custom module which provides auth-config-factory. This custom module must reference an XML file which sets a new instance of the AuthConfigFactory with the static method AuthConfigFactory.setFactory(). For an example of this see the ee10-jaspi-default-auth-config-factory module, which provides the default implementation used by Jetty.

# DO NOT EDIT THIS FILE - See: https://jetty.org/docs/

[description]
Provides a DefaultAuthConfigFactory for jaspi

[environment]
ee10

[tags]
security

[depend]
ee10-security

[provide]
auth-config-factory

[xml]
etc/jaspi/jetty-ee10-jaspi-default.xml