back to all blogsSee all blog posts

Java SE 19 and distributed security cache support in Open Liberty 22.0.0.11

image of author
Michal Broz on Oct 25, 2022
Post available in languages: 日本語 ,

Open Liberty 22.0.0.11 provides support for Java SE 19 and distributed security caches. Java SE 19 includes many new exciting features and changes such as record patterns and virtual threads. Distributed security cache support allows multiple Liberty servers to share caches by using a JCache provider.

As part of 22.0.0.11, you can now also implement SPI interfaces with BELL services and enable BELL services to receive configuration properties. These BELL feature enhancements provide a simpler alternative to writing a user feature. This release also includes an important security vulnerability (CVE) fix and many notable bug fixes.

In Open Liberty 22.0.0.11:

View the list of fixed bugs in 22.0.0.11.

Run your apps using 22.0.0.11

If you’re using Maven, here are the coordinates:

<dependency>
    <groupId>io.openliberty</groupId>
    <artifactId>openliberty-runtime</artifactId>
    <version>22.0.0.11</version>
    <type>zip</type>
</dependency>

Or for Gradle:

dependencies {
    libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '[22.0.0.11,)'
}

Or if you’re using Docker:

FROM open-liberty

Or take a look at our Downloads page.

Ask a question on Stack Overflow

Java SE 19 support

Java SE 19 has been released and with it the following features:

Although Java SE 19 was not supported in 22.0.0.10 at the time of that version’s release, it has been retroactively backported. Therefore, Java SE 19 is officially supported with Open Liberty 22.0.0.10 and newer. To give this a try today, download Java SE 19, download and install at least the 22.0.0.10 version of Open Liberty, edit your Liberty server’s server.env file to point JAVA_HOME to your Java SE 19 installation and start testing!

For more information on Java SE 19, please visit the Java SE 19 release notes page or API Javadoc page. For more information, refer to the Java SE support page.

To try out Java SE 19 preview features in Open Liberty, make sure to add --enable-preview to your jvm.options file.

Distributed security caches

Distributed security cache support is introduced so that multiple Liberty servers can share caches by using a JCache provider. Before this release, the authentication (subject) cache and logged-out cookie cache were both restricted to be local and in-memory. Multiple servers were unable to benefit from their peers' caches and each server started with a cold cache. As part of this update, both caches can be stored in a distributed JCache provider. This update can improve performance and failure recovery, reduce the load on backend user registries, reduce redundant redirects to the IDP, and improve the security posture of the server.

Configuring a distributed authentication cache

The server.xml file examples in this section specify the appSecurity-3.0 feature but you can use any version of the Jakarta Security (Application Security) feature to configure a distributed authentication cache.

Because the creation of a subject might affect performance, Liberty provides an authentication cache to store a subject after an authentication of a user is successful. The authentication cache now can be distributed using a 3rd party JCache provider. The jCacheLibraryRef references the library that contains the JCache caching provider implementation. To configure the distributed authentication cache, use the following server.xml configuration:

    <featureManager>
        <feature>appSecurity-3.0</feature>
    </featureManager>

    <!--
        The 3rd-party JCache provider library that Liberty will use to manage and connect to the cache.
     -->
    <library id="JCacheProviderLib">
        <fileset dir="${shared.resource.dir}" includes="jcacheprovider.jar" />
    </library>

    <!--
        Configure the JCache cache instance.
     -->
    <cache id="AuthCache" name="AuthCache">
        <cacheManager uri="uri://someuri">
            <properties prop1="value1" prop2="value2" />

            <cachingProvider jCacheLibraryRef="JCacheProviderLib" />
        </cacheManager>
    </cache>

    <!--
        Configure the authentication cache.
     -->
    <authCache cacheRef="AuthCache" />

If your Liberty environment injects custom principals or credentials into your subject, such as in a custom LoginModule or Trust Association Interceptor (TAI), they must be Serializable in order to store them in the distributed authentication cache. Additionally, the shared library that contains those classes must be available to the caching provider and any other configurations that need access to those classes. If the same shared library is not used for each, ClassCastExceptions might be encountered when working with the classes retrieved from the distributed cache. The commonLibraryRef is optional and can reference libraries that contain any custom classes that may be serialized and stored in the cache. You can define multiple libraries by separating them by a comma.

<featureManager>
    <feature>appSecurity-3.0</feature>
</featureManager>

<!--
    The 3rd-party JCache provider library that Liberty will use to manage and connect to the cache.
 -->
<library id="JCacheProviderLib">
    <fileset dir="${shared.resource.dir}" includes="jcacheprovider.jar" />
</library>

<!--
    This shared library contains any custom credentials and/or principals that
    are stored in the subject.
 -->
<library id="CustomLib">
    <fileset dir="${shared.resource.dir}" includes="customlibrary.jar" />
</library>

<cache ... >
    <cacheManager ... >
        <cachingProvider jCacheLibraryRef="JCacheProviderLib" commonLibraryRef="CustomLib" />
    </cacheManager>
</cache>

<!--
    Some sample JAAS custom login module configuration. The custom login module
    in this example would inject custom credentials or principals into the subject.

    Note that the 'libraryRef' in the 'jaasLoginModule' needs to be set to the same
    library referenced from the caching provider.
 -->
<jaasLoginContextEntry id="system.WEB_INBOUND"
    name="system.WEB_INBOUND"
    loginModuleRef="custom, hashtable, userNameAndPassword, certificate, token" />

<jaasLoginModule id="custom"
    className="org.acme.CustomLoginModule"
    controlFlag="REQUIRED" libraryRef="CustomLib" />

<!--
    Any applications that will be accessing classes from the Subject also need
    to use the same library reference.
 -->
<application ...>
    <classloader commonLibraryRef="CustomLib" />
</application>

A few points to consider when configuring a JCache for use with the authentication cache.

  • The distributed authentication cache is comprised of keys and values of type Object. To match the behavior of the local authentication cache, set a least recently used eviction (LRU) policy with a maximum entry count of 25000 and an entry TTL of 600 seconds. Note that with distributed caches, partitioning of the cache can lead to an actual capacity below the configured value.

  • If your JCache provider supports it, configure a client-side cache to reduce transactions to the distributed cache. If the client-side cache supports storing the entries as deserialized objects, this can further improve performance.

  • Subjects in the distributed cache should be treated as you would treat other security-sensitive information, such as usernames and passwords. Configure your JCache provider to secure the data while it is in motion and at rest. These precautions include encryption and access control.

For more information, check out Distributed caching with JCache.

The logged-out cookie cache stores LTPA and JWT cookies that have been logged-out. The logged-out cookie cache can now be distributed using a 3rd party JCache provider, which ensures that logged-out cookies are enforced across multiple servers. To configure the distributed logged-out cookie cache, use the following server.xml configuration:

    <featureManager>
        <feature>appSecurity-3.0</feature>
    </featureManager>

    <!--
        The 3rd-party JCache provider library that Liberty will use to manage and connect to the cache.
     -->
    <library id="JCacheProviderLib">
        <fileset dir="${shared.resource.dir}" includes="jcacheprovider.jar" />
    </library>

    <!--
        Configure the JCache instances.
     -->
    <cache id="LoggedOutCookieCache" name="LoggedOutCookieCache">
        <cacheManager uri="uri://someuri">
            <properties prop1="value1" prop2="value2" />

            <cachingProvider jCacheLibraryRef="JCacheProviderLib" />
        </cacheManager>
    </cache>

    <!--
        Configure the authentication cache to use the JCache.
     -->
    <webAppSecurity loggedoutCookieCacheRef="LoggedOutCookieCache" />

A few points to consider when configuring a JCache cache for use with the logged-out cookie cache.

  • The distributed logged-out cookie cache is comprised of keys and values of type Object.

  • To match the behavior of the local logged-out cookie cache, configure the cache with a maximum entry count of 10000 and an entry TTL of unlimited. Note that with distributed caches, partitioning of the cache can lead to an actual capacity below the configured value. The cache capacity should be large enough that no cookies that have not expired will be evicted due to new logged out cookies being inserted into the cache.

  • If your JCache provider supports it, configure a client-side cache to reduce transactions to the distributed cache. If the client-side cache supports storing the entries as deserialized objects, this can further improve performance.

For more information, check out Track logged-out SSO cookies.

Configuring a distributed session cache

The sessionCache-1.0 feature has been updated to allow use of the new distributed cache configuration elements to allow common configuration across all features that use JCache. This eliminates the need to configure JCache separately for the session cache.

    <featureManager>
        <feature>sessionCache-1.0</feature>
    </featureManager>

    <!--
        The 3rd-party JCache provider library that Liberty will use to manage and connect to the cache.
     -->
    <library id="JCacheProviderLib">
        <fileset dir="${shared.resource.dir}" includes="jcacheprovider.jar" />
    </library>

    <!--
        Configure the JCache cache manager.
     -->
    <cacheManager id="CacheManager" uri="uri://someuri">
        <properties prop1="value1" prop2="value2" />

        <cachingProvider jCacheLibraryRef="JCacheProviderLib" />
    </cacheManager>

    <!--
        Configure the HTTP session cache.
     -->
    <httpSessionCache cacheManagerRef="CacheManager" ... />

Configuring multiple caches

When configuring multiple distributed caches, instead of nesting the cacheManager configuration element within the cache element, the cache element needs to refer to the cache manager via the cacheRef attribute.

    <featureManager>
        <feature>appSecurity-3.0</feature>
        <feature>sessionCache-1.0</feature>
    </featureManager>

    <!--
        The 3rd-party JCache provider library that Liberty will use to manage and connect to the cache.
     -->
    <library id="JCacheProviderLib">
        <fileset dir="${shared.resource.dir}" includes="jcacheprovider.jar" />
    </library>

    <!--
        Configure the JCache cache manager.
     -->
    <cacheManager id="CacheManager" uri="uri://someuri">
        <properties prop1="value1" prop2="value2" />

        <cachingProvider jCacheLibraryRef="JCacheProviderLib" />
    </cacheManager>

    <!--
        Configure the JCache cache instances.
     -->
    <cache id="AuthCache" name="AuthCache" cacheManagerRef="CacheManager" />
    <cache id="LoggedOutCookieCache" name="LoggedOutCookieCache" cacheManagerRef="CacheManager" />

    <!--
        Configured the authentication cache, logged-out cookie cache and HTTP session cache.
     -->
    <authCache cacheRef="AuthCache" />
    <webAppSecurity loggedoutCookieCacheRef="LoggedOutCookieCache" ... />
    <httpSessionCache cacheManagerRef="CacheManager" ... />

To find out more, check out the authentication and authCache elements enabled by the appSecurity feature, as well as the JCache Session Persistence examples.

Implement SPI interfaces with BELL services and enable BELL services to receive configuration properties

The Basic extensions using Liberty libraries (BELL) 1.0 feature enables shared libraries to provide implementations of Liberty API interfaces using Java ServiceLoader configuration files.

22.0.0.11 introduces two capabilities for BELL services: SPI visibility, and properties configuration and injection. Previously, these capabilities were available only to user feature extensions. User features offer more capabilities than BELL services, but come with a more complex development model. These capabilities allow extension developers greater opportunity to leverage the simplicity of BELL services.

BELL SPI visibility makes feature SPI packages visible only to shared libraries referenced in BELL configurations. The introduction of BELL SPI visibility enables developers to provide implementations of SPI interfaces as BELL services rather than user features, which typically require more time to develop.

BELL properties configuration and injection enables BELL services to receive properties configured in the server.xml file. The introduction of BELL properties allows users to exploit the benefits of the Liberty configuration and obviates the need to configure BELL services with environment variables or JVM system properties.

SPI visibility for shared libraries

Shared libraries do not support access for SPI packages. The introduction of BELL SPI visibility enables libraries to provide implementations of Liberty SPI interfaces by making SPI packages accessible to shared libraries referenced in a bell configuration.

Use the new spiVisibility configuration attribute to indicate whether SPI packages are accessible to a library. Set the attribute to true whenever a library provides an implementation of an SPI interface:

<server>
    <featureManager>
        <feature>bells-1.0</feature>
    </featureManager>
    ...
    <bell libraryRef="servicesLib" spiVisibility="true"/>
</server>

For the previous example, the BELL feature loads the service implementation classes discovered in library serviceLib by using a specialized classloader that can see SPI packages in addition to the library binaries and API types.

Properties configuration and injection

The introduction of BELL properties enables service implementations to receive properties declared in the bell configuration. The new capability obviates the use of environment variables and JVM system properties to configure BELL services.

Use the new properties element to configure one or more properties in a bell configuration. Declare each property as a name="value" attribute within the element. Properties are type String and inject into all service implementations that are enabled to receive them. The following example declares two properties, hello and serverHome:

<server>
    <featureManager>
        <feature>bells-1.0</feature>
    </featureManager>
    ...
    <bell libraryRef="servicesLib">
        <properties hello="WORLD" serverHome="${server.output.dir}" />
    </bell>
</server>

To enable a service implementation to receive configuration properties, define either a public method named updateBell or a public constructor in the service implementation class. The method signature must declare a single parameter of type java.util.Map<String,String>.

public YourServiceImpl(java.util.Map<String,String> bellProperties) {...}
// OR
public void updateBell(java.util.Map<String,String> bellProperties) {...}

At service creation, the BELL feature discovers the method and invokes it to inject an unmodifiable map containing a key/value pair for each property. For the previous example, the map contains the pairs "hello"/"WORLD" and "serverHome"/"<resolved value of ${server.out.dir}>".

To find out more, see:

Security vulnerability (CVE) fixes in this release

CVE CVSS Score Vulnerability Assessment Versions Affected Notes

CVE-2022-24839

7.5

Denial of service

17.0.0.3 - 22.0.0.10

Affects the OpenID 2.0 feature

For a list of past security vulnerability fixes, reference the Security vulnerability (CVE) list.

Notable bugs fixed in this release

We’ve spent some time fixing bugs. The following sections describe just some of the issues resolved in this release. If you’re interested, here’s the full list of bugs fixed in 22.0.0.11.

  • HTTP Access logging need to log multiple X-Forwarded-For headers

    Prior to the fix, the HTTP Access logging would only log one X-Forwarded-For header per request instead of all of them.

    This issue is now resolved and all the X-Forwarded-For headers get properly logged.

  • MYFACES-4450: tabindex not rendered for outputLabel

    The h:outputLabel fails to render the tabindex attribute in a JSF page. For example, <h:outputLabel tabindex="2" value="test"/> renders as <label>test</label> instead of <label tabindex="2">test</label>.

    The issue has now been resolved and the correct output gets rendered.

  • Cannot start Jenkins 2.346.3 with Java 17 when using AD authentication

    When using OpenLiberty 22.0.0.9 running on Java SE 17 the following FFDC can occur:

    0000002f com.ibm.ws.logging.internal.impl.IncidentImpl                I FFDC1015I: An FFDC Incident has been created: "java.lang.IllegalAccessException: class com.ibm.ws.jndi.internal.WASInitialContextFactoryBuilder cannot access class com.sun.jndi.dns.DnsContextFactory (in module jdk.naming.dns) because module jdk.naming.dns does not export com.sun.jndi.dns to unnamed module @3ce42ee7 com.ibm.ws.jndi.internal.WASInitialContextFactoryBuilder 58" at ffdc_22.08.31_18.04.56.0.log

    The issue has been resolved by exporting the jdk.naming.dns module.

  • Yoko marshals null fields incorrectly when the field is declared as a non-serializable class

    When Yoko is marshalling a Java value object with a null field that is declared as a non-serializable class, it is marshalled incorrectly. This does not cause any problems when two Liberty processes are communicating over IIOP, but it can cause problems when interoperating with other Java processes.

    The objects are now marshalled correctly, resolving the issue.

  • com.ibm.websphere.appserver.api.kernel.service_1.1-javadoc.zip is missing in the Liberty images

    When using a Liberty image, the com.ibm.websphere.appserver.api.kernel.service_1.1-javadoc.zip file does not exist in the dev/api/ibm/javadoc directory.

    The issue has been resolved and the javadoc zip is now correctly included in the dev/api/ibm/javadoc directory.

Get Open Liberty 22.0.0.11 now