back to all blogsSee all blog posts

MicroProfile GraphQL 2.0, Java 18 support, and distributed security caches on Open Liberty 22.0.0.4-beta

image of author
Ryan Storey on Mar 17, 2022
Post available in languages:

Open Liberty 22.0.0.4-beta offers GraphQL 2.0, which incorporates Jakarta EE 9.1 dependencies, and Java 18 support, which includes many new exciting features and changes. Also included in this release is distributed security cache support, which allows multiple Liberty servers to share caches via a JCache provider.

The Open Liberty 22.0.0.4-beta includes the following beta features and function (along with all GA features and function):

MicroProfile GraphQL 2.0

MicroProfile GraphQL 2.0 incorporates Jakarta EE 9.1 dependencies. This allows developers to continue using the same functionality provided by MP GraphQL 1.0 but with the updated Jakarta features such as CDI 3.0, restfulWS 3.0, JSON-B 2.0, etc. Functionally, version 2.0 behaves the same as 1.0 because it uses the same version of the underlying implementation (SmallRye GraphQL). If you’d like to learn more about MP GraphQL, see our previous blog post about MP GraphQL 1.0 and our blog post on how to use the GraphiQL UI and third-party Client APIs.

To enable the MicroProfile GraphQL 2.0 beta feature in your app, add it to your server.xml:

<featureManager>
  <feature>mpGraphQL-2.0</feature>
</featureManager>

Java 18 Support

Java 18 is coming soon, and with it the following features and changes:

Java Security support has been removed with Java 18+ in Liberty. If "websphere.java.security" is set in bootstrapping.properties, it will produce the following error in the log:

CWWKE0955E: Java Security was requested in bootstrapping.properties while using JDK "18", however this option is no longer valid when using Java 18 and later.

By trying out Java 18 now, you get more time to review your applications, microservices, and runtime environments and you’ll be a step ahead when it becomes generally available.

To give this a try today, download the early access release of Java 18, install 22.0.0.4-beta version of Open Liberty, edit your Liberty server’s server.env file to point JAVA_HOME to your Java 18 installation and start testing!

For more information on Java 18, please visit the Java 18 release notes page, API Javadoc page or download page. For more information on Open Liberty, please visit our documentation page.

If you find anything amiss, let us know.

Distributed Security Caches

Distributed security cache support has been introduced so that multiple Liberty servers can share caches via a JCache provider. Prior to this feature, the authentication (subject) and logged out cookie caches were 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 feature, both caches can be stored in a distributed JCache provider. This can improve performance and failure recovery, reduce the load on backend user registries, and improve the security posture of the server.

When using the new distribute caching functionality in this beta release, the feature distributedSecurityCache-1.0 needs to be included in the list of features in the server.xml file. This beta-only feature exposes the JCache APIs to the 3rd party JCache provider.

Configuring 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. To configure the distributed authentication cache, use the following server.xml configuration:

    <featureManager>
        <feature>appSecurity-3.0</feature>
        <feature>distributedSecurityCache-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 instance.
     -->
    <cache id="AuthCache" name="AuthCache">
        <cacheManager uri="uri://someuri">
            <properties prop1="value1" prop2="value2" />

            <cachingProvider libraryRef="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.

<featureManager>
    <feature>appSecurity-3.0</feature>
    <feature>distributedSecurityCache-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>

<!--
    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>

<!--
    Take notice that the 'libraryRef' attribute has both library references.
 -->
<cache ... >
    <cacheManager ... >
        <cachingProvider libraryRef="JCacheProviderLib,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.

  • Support in the beta is currently limited to LTPA and JWT. Single sign-on methods such as SPNEGO, Oauth, OIDC and SAML (etc) are not yet supported

  • 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. This should include encryption and access control.

Configuring a Distributed Logged-Out Cookie Cache

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 ensuring 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>
        <feature>distributedSecurityCache-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 instances.
     -->
    <cache id="LoggedOutCookieCache" name="LoggedOutCookieCache">
        <cacheManager uri="uri://someuri">
            <properties prop1="value1" prop2="value2" />

            <cachingProvider libraryRef="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.

Configuring a Session Cache with the new Distributed Cache Configuration

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>distributedSecurityCache-1.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 libraryRef="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>distributedSecurityCache-1.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 libraryRef="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.

Try it now

To try out these features, just update your build tools to pull the Open Liberty All Beta Features package instead of the main release. The beta works with Java SE 18, Java SE 11, or Java SE 8.

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

<dependency>
  <groupId>io.openliberty.beta</groupId>
  <artifactId>openliberty-runtime</artifactId>
  <version>22.0.0.4-beta</version>
  <type>pom</type>
</dependency>

Or for Gradle:

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

Or take a look at our Downloads page.

Your feedback is welcomed

Let us know what you think on our mailing list. If you hit a problem, post a question on StackOverflow. If you hit a bug, please raise an issue.