Version 0.10.x

Version 0.10.x

Version 0.10.0 (previous stable release)

Release date: 2024-05-16

For a complete list of issues addressed in this release, see Metadata Aggregator | Releases | 0.10.0Released.

This is a major pre-1.0 feature release. The intention is to stabilise the API as much as possible in advance of the 1.0.0 release of the product. There are many changes to the API in this release, and you should expect to make changes in your deployment when migrating from previous releases. Where possible, deprecation warnings are logged to allow gradual migration. Some of those deprecations (to be determined) will be resolved by removing the old APIs in v1.0.0; others will be retained past that point.

This release introduces a standard bean definition resource which both simplifies XML configuration and assists in migration from older versions of the API. Deployers are strongly recommended to adopt this approach if using XML configuration. See Standard bean definition resource for full details.

Dependency Changes

  • MDA-274: This release is built with Java 17, and requires a Java 17 or later execution environment. The distribution is now bundled with Spring Framework V6.x, up from V4.x, and with the new refactored Shibboleth shared dependencies replacing java-support and spring-extensions. This aligns the MDA with V5.x of the IdP product.

Packaging Changes

In version 0.10.0, the packaging of the Metadata Aggregator has been completely revised:

  • MDA-266: In prior versions, a single distribution package in .zip format was provided bundling a simple command-line interface, the MDA framework and all required dependencies, with a name like aggregator-cli-0.9.2-bin.zip. In version 0.10.0, two distribution packages are available:

    • mda-distribution-0.10.0.tar.gz, intended for non-Windows systems, and

    • mda-distribution-0.10.0.zip, intended for Windows systems.

Each package includes, as before, the MDA framework, the simple command-line interface and all required dependencies. Additional text files such as license material and examples follow Windows line endings for the .zip distribution and Unix line endings for the .tar.gz distribution. Both distributions include invocation scripts for both Linux (mda.sh) and Windows (mda.bat) systems following the natural line-ending conventions for their intended platforms.

By preference, you should use the .zip distribution only on Windows systems. If you are migrating from 0.9.x on a non-Windows system, you should switch to the .tar.gz distribution instead. However, the .zip distribution still includes the Linux invocation script with Unix-style line endings so it will still work. This behaviour is not guaranteed for future releases.

  • MDA-266: Maven artifact IDs for the JAR artifacts have changed:

    • aggregator-pipeline is now mda-framework

    • aggregator-cli is now mda-cli

The group ID remains net.shibboleth.metadata.

  • MDA-158: The packaging of the RSA key list resources introduced in version 0.9.0 has been changed. Previously included in the aggregator-pipeline artifact, these resources have now been moved into two separate artifacts: mda-keylists-rsa for most use cases and mda-keylists-rsa-legacy for legacy applications in which shorter RSA keys (with a modulus of less than 2048 bits) are in use. The resource names have also changed to prevent split package issues in the Java module system. This means that if your application does not use these resources, it may decrease in size by around 13MB. Applications making use of the key list resources may need to add a dependency on mda-keylists-rsa or, in rare cases, mda-keylists-rsa-legacy. The resources provided are:

    • In mda-keylists-rsa:

      • net/shibboleth/metadata/keylists/rsa/compromised-2048.txt

      • net/shibboleth/metadata/keylists/rsa/compromised-4096.txt (new in 0.10.0)

      • net/shibboleth/metadata/keylists/rsa/debian-2048.txt

      • net/shibboleth/metadata/keylists/rsa/debian-4096.txt

    • In mda-keylists-rsa-legacy:

      • net/shibboleth/metadata/keylists/rsa/legacy/compromised-1024.txt

      • net/shibboleth/metadata/keylists/rsa/legacy/debian-1024.txt

      • net/shibboleth/metadata/keylists/rsa/legacy/debian-512.txt

  • MDA-290: The packaged mda-module JAR files are now sealed. This means that classes within these artifacts may not be overridden by other resources on the classpath.

  • JPAR-113: The packaged mda-module JAR files, as well as a number of underlying library JARs have been given automatic module names as described in Java Modularity, for future potential use on the Java module path. Note that this version of the Shibboleth Metadata Aggregator has not been tested on, and is therefore not guaranteed to work on, the Java module path.

API Removals

One aim of this release is to prepare for a stable 1.x release series. As part of this, a number of elements have been removed from the API:

  • MDA-192: The ancestorEntity method has been removed from AbstractDOMTraversalStage; a protected errorPrefix method has replaced it in order to allow sub-classes to replicate this or similar behaviour. A new AbstractSAMLTraversalStage class has been added to incorporate the specific old behaviour.

  • MDA-203: A number of classes which were not originally intended to be part of the API have been moved to implementation packages whose names include “.impl". You should not access these classes, as they may be changed, renamed or removed in any future version of the product. The classes include:

    • FutureSupport

    • PipelineCallable

    • XMLSignatureValidator

  • MDA-223: A number of constant fields have been removed from the XMLSignatureSigningStage and XMLDSIGSupport classes and therefore the API, as they are now part of the base Java API. For example, XMLSignatureSigningStage.ALGO_ID_SIGNATURE_RSA_SHA256 is replaced by Java's SignatureMethod.RSA_SHA256.

  • MDA-249: The decorated collection class ItemCollectionWithMetadata has been removed. There is no replacement for this functionality, but it was only sporadically supported in the framework and has no real-world use as far as we are aware.

  • MDA-250: The ItemMetadataSupport class has been removed. The addAll methods provided by this class are more simply implemented in calling classes by direct operation on an item's getItemMetadata() result. Note, in particular, that ClassToInstanceMultiMap provides a putAll variant which can be passed another ClassToInstanceMultiMap of the same type. This leads to statements such as new.getItemMetadata().putAll(old.getItemMetadata()); as the optimal way to copy one item's item metadata collection into another item.

  • MDA-259: The FutureSupport.futureNow method has been removed. Use the JDK’s CompletableFuture class instead.

  • MDA-281: The ComponentInfo class has been removed, along with the supporting logic. This was intended to be used for performance monitoring, but presented performance issues of its own. The progress logging facility added in MDA-282 (see below) addresses many of these use cases in a much more convenient way.

  • MDA-303: The SAMLMetadataSupport.addDescriptorExtension method has been removed. The Container framework can be used as a replacement.

  • JSE-28: This release bundles a new version of the Shibboleth support library for Spring, which removes support for SVN-based resources.

API Additions

  • MDA-52: A new stage ElementsStrippingStage has been added to allow stripping a number of different elements (all from the same namespace) from a DOM document. The stage may be operated in a blacklisting or whitelisting mode, with blacklisting the default. Like ElementStrippingStage, an elementNamespace property determines the namespace in question, and all elements in other namespaces are ignored.

  • MDA-56: A new stage EntityAttributeAddingStage has been added to add entity attributes to the metadata for SAML entities. This is configured using attributeNameattributeNameFormat and attributeValue properties, with attributeName and attributeNameFormat defaulting to the values required to add an entity category attribute. The stage is based on a new Container framework which attempts to generate reasonably well formatted XML for nested container elements, and handles the insertion of the required parent containers (Extensions, EntityAttributes, Attribute) when they are not already present.

  • MDA-116: The ScriptletStage has a new variableName property controlling the name of the variable in the script context to which the item list is assigned. This defaults to "items" as before but may be overridden for languages or scripts that require a different value. For example, setting variableName to "$items" allows use of the stage with Ruby.

  • MDA-138: A new SAMLStringElementCheckingStage can be used to check the general rule in SAML that elements with string values must have at least one non-whitespace character.

  • MDA-160: The EntityAttributesFilteringStage has been extended with a new recordingRemovals property, defaulting to false. If recordingRemovals is set to true, each removed entity attribute is recorded as a WarningStatus in the item's item metadata, indicating the name and value of the entity attribute removed. This can then be processed by subsequent stages, such as a StatusMetadataLoggingStage.

  • MDA-173: A new DiscoFeedCollectionSerializer can be used in conjunction with the existing SerializationStage to generate a JSON discovery feed compatible with the Shibboleth Embedded Discovery Service (EDS), as an alternative to the Shibboleth SP's ability to generate such a feed at its /DiscoFeed endpoint. A configuration example is available. The following properties may be set; all are false by default:

    • prettyPrinting creates more human-readable output using white space, this is the Shibboleth SP's default but is disabled by default for the DiscoFeedCollectionSerializer.

    • includingLegacyDisplayNames is equivalent to the SP's legacyOrgNames attribute.

    • includingEntityAttributes is equivalent to the SP's tagsInFeed attribute.

  • MDA-177: An entity attribute matcher AssuranceCertificationMatcher has been added to allow simpler matching of entity attributes containing assurance certifications, such as that used by the SIRTFI framework.

  • MDA-178, MDA-294: A Standard bean definition resource has been added to simplify access to each bean class in the mda-framework artifact. In XML configuration, this can be accessed by <import resource="classpath:net/shibboleth/metadata/beans.xml"/>. One abstract bean is defined for each available bean class, named after the class's simple name prefixed by "mda.". After including this resource, for example, class="net.shibboleth.metadata.dom.XMLSignatureValidationStage" can be replaced by parent="mda.XMLSignatureValidationStage"; this definition will also include the init-method and destroy-method properties for the bean when appropriate. This resource also implements MDA-277 to provide migration assistance from old releases of the MDA.

  • MDA-179: The simple command-line interface now includes a --version option to request the printing of the framework version number.

  • MDA-184: A new utility class RegexFileFilter has been added to support one of the common use cases of the DOMFilesystemSourceStage, where only certain files should be processed from a directory, based on their names.

  • MDA-187: A new IPHintValidationStage  has been added to allow validation of <mdui:IPHint> elements in SAML metadata. The checkingNetworks property (default true ) requires that the value represents a network and not a host, thus faulting values such as "127.0.0.1/24".

  • MDA-193: To make using the Validator framework more straightforward, the new ValidatorSequence class abstracts the concept of  a sequence of Validators which can be maintained and applied as a group. Existing classes requiring this behaviour have been refactored to take advantage of ValidatorSequence.

  • MDA-199: A new X509ROCAValidator component allows RSA public keys in X.509 certificates to be checked for vulnerability to ROCA (the Return of Coppersmith's Attack, also known as CVE-2017-15361).

  • MDA-200: The BaseValidator abstract class has been extended to add an addErrorMessage method and a message property, which acts as a format string for ErrorStatus item metadata generated through addErrorMessage.

  • MDA-201: New AcceptAllValidator and RejectAllValidator components have been added. Both always return Action.DONE so that they can be used to terminate a sequence of validators. AcceptAllValidator has no other functionality; RejectAllValidator uses its message property to format an appropriate ErrorStatus for the Item on which validation is being performed.

  • MDA-202: Four new validator components (AcceptStringValueValidatorRejectStringValueValidatorAcceptStringRegexValidator and RejectStringRegexValidator) have been added to match String values. All four return Action.DONE if the match occurs and will therefore terminate a sequence of validators; Action.CONTINUE is returned otherwise. The Reject forms also add a formatted ErrorStatus on matching.

  • MDA-214: A new X509DSADetector component allows DSA keys in metadata to be rejected, or merely warned about.

  • MDA-229: A new StringElementValidationStage component allows the validation of the string contents of designated DOM elements. Use setElementNames (set the elementNames property) to specify collection of element names to validate. A second method (setElementName, or set the elementName property) provides a shortcut for the common single-element case.

  • MDA-231: A new StringAttributeValidationStage component allows the validation of the string contents of designated DOM attributes. Its API mirrors that of StringElementValidationStage with the addition of a setAttributeNames method (an attributeNames property) to specify a collection of attributes to validate on the selected elements. setAttributeName (an attributeName property) provides a shortcut for the common single-attribute case.

  • MDA-233: The Validator interface has been extended with a second validate method with an additional String valueContext parameter. This provides a way for a caller to provide context about the validation so that error messages can be more helpful: for example, a failed validation of a particular component in a URL can refer to the entire URL as well as the rejected component value. Both validate methods are provided with default bodies, so that existing Validator implementations work without change: new implementations must implement at least one of the methods, but this can be either one. Within the aggregator framework, this functionality has been retrofitted to many existing classes so that the valueContext is propagated through a validator hierarchy, and the new Validator<URL> classes make use of the value in reporting (see MDA-299 below).

  • MDA-234: A new ItemOrderingStage allows the collection of entities to be re-ordered according to a supplied ItemOrderingStrategy<T> (the default strategy does not change the ordering).

  • MDA-282: CompositeStage and SimplePipeline now support a boolean loggingProgress property which, if enabled, causes instances to log progress through the configured stages at the INFO level. Execution of each stage is surrounded by an indication of the number of items being processed as well as the elapsed time for processing, and a final composite elapsed time is logged at the end.
    This feature is enabled for all instances of CompositeStage and SimplePipeline regardless of their loggingProgress property if the system property net.shibboleth.metadata.loggingAllProgress is set to true. This is intended to allow an initial overall view of processing time before digging in to specific instances of CompositeStage later.

  • MDA-287: A new ScopeValidationStage component has been added to allow the checking of <shibmd:Scope> elements in SAML metadata. The stage accepts two lists of Validator<String>, one for scopes where regex="false" or absent, and another for scopes where regex="true". Additional validator components AsLiteralTailStringValidator, AsDomainNameStringValidator, RejectDomainNameNotUnderPublicSuffixValidator and RejectDomainNamePublicSuffixValidator have also been added to allow the construction of the kind of complex validator policy required in this area. An example of the kind of policy detail achievable with this mechanism (which has been used for some years in the InCommon federation and the UK federation) can be found in this test case.

  • MDA-288: A new DuplicateEntityInAggregateCheckingStage allows checking of SAML metadata aggregates to ensure that they do not include entities with duplicate entityID values.

  • MDA-289: A new FixedStringIdentifierGenerationStrategy had been added for use when it is not necessary to use different ID attribute values for different documents.

  • MDA-299: A new AsURLStringValidator allows validating string values (such as DOM attributes using StringAttributeValidationStage) as URLs. Additional validators may then be applied to the resulting URL: HTTPSOnlyURLValidator, EmptyPortURLValidator and MissingHostURLValidator are provided for common use cases.

  • MDA-301: The BaseAsValidator class now includes detail from an IllegalArgumentException resulting from a failed conversion in the resulting error message. The extended addErrorMessage method used to implement this is also available for use by other BaseValidator subclasses.

API Changes

  • MDA-166: The ItemSerializer and ItemCollectionSerializer interfaces now allow serializers to throw IOException when appropriate. The provided DOMItemSerializer will throw an IOException wrapping a TransformerException if the latter is thrown during XML serialization. Previously, this condition would only have resulted in logging at ERROR level.

  • MDA-167: The ItemIdTransformStage now transforms identifiers using a collection of Function objects rather than of the similar Converter provided by the Spring framework. This also affects the type of the MDQueryMD5ItemIdTransformer and MDQuerySHA1ItemIdTransformer classes. This change will not affect existing configurations if only those classes are in use. This matches the use of Function elsewhere in the API.

  • MDA-169: The SAMLMetadataSupport.getDescriptorExtensions method has been renamed to getDescriptorExtension to reflect the fact that it returns a single result.

  • MDA-170: The PKCS11PrivateKeyFactoryBean temporarily introduced in v0.9.2 has, as indicated for that release, moved to the spring-extensions module; configurations will need to be adjusted accordingly:
    Old class name: net.shibboleth.metadata.util.PKCS11PrivateKeyFactoryBean
    New class name: net.shibboleth.ext.spring.factory.PKCS11PrivateKeyFactoryBean

  • MDA-171: The SAMLMetadataSupport.getDescriptorExtension method's parameters must now be non-null; their annotations have been changed to @Nonnull to correspond with this. In previous releases, they were annotated as @Nullable and passing null would result in the method returning null.

  • MDA-175: The ItemOrderingStrategy interface defined by the EntitiesDescriptorAssemblerStage now allows the ordering strategy to throw a StageProcessingException if, for example, the items presented are invalid in some way and can not be ordered. Such an exception will be propagated upwards to the caller of the stage's execute method.

  • MDA-179: The Version class's getMicroVersion method has been renamed to getPatchVersion to align with current (semantic versioning) terminology.

  • MDA-182: Several classes exposed as part of the API for building custom stages have been reworked to simplify implementation of other stages and to correspond to current naming conventions:

    • BaseStage has been renamed to AbstractStage

    • BaseIteratingStage has been renamed to AbstractFilteringStage

    • A new AbstractIteratingStage allows the simpler construction of stages which process each Item independently

  • MDA-188: The AbstractDOMTraversalStage framework has been generalised to allow the use of custom context objects specific to the particular traversal, rather than relying on sometimes tortured uses of the ClassToInstanceMultiMap to carry everything. This is a breaking change, but will only affect writers of stages derived from AbstractDOMTraversalStage:

    • Context objects must implement the DOMTraversalContext interface. This no longer includes the getStash method (returning a ClassToInstanceMultiMap but does add a new end() method to be called at the end of the traversal.

    • A basic implementation of SimpleDOMTraversalContext is provided without any data fields. This can be used in many cases where custom storage is not required in the context; for an example, see AbstractElementVisitingStage.

    • More complex cases can extend SimpleDOMTraversalContext to include additional fields and method. For a very straightforward example, see CRDetectionStage. A more complex example, including use of the end() method from DOMTraversalContext, can be found in ElementsStrippingStage.

  • MDA-198: In previous releases, the three X.509 validation component (X509RSAExponentValidatorX509RSAKeyLengthValidator and X509RSAOpenSSLBlacklistValidator) all set a default ID related to their names (e.g., RSAKeyLength). This default ID setting behaviour has been removed. This may have two effects on configurations which do not explicitly set the component ID:

    • If a configuration did not set the component ID, initializing the component will now fail with a ComponentInitializationException.

    • Configurations that implicitly set the component ID to a defaulted Spring component ID using IdentifiableBeanPostProcessor may give different results, as the Spring component ID may now appear in status objects replacing the previous default.

  • MDA-191: The stages PullUpCacheDurationStage, PullUpValidUntilStage, SetCacheDurationStage, SetValidUntilStage and ValidateValidUntilStage now use the Instant and Duration classes (introduced in Java 8) in their APIs rather than using long values representing milliseconds as in previous releases.

    • This aligns the metadata aggregator with other Shibboleth projects based on the Java 11 platform. If you use the Java language to configure these stages, you will need to re-code appropriately; in most cases, this can be done quickly using Instant.fromEpochMilli() and Duration.ofMillis(), but we recommend adopting the modern java.time classes throughout.

    • The DurationToLongConverter is no longer included as part of the java-support dependency. If you were using it as part of an XML configuration to specify durations in ISO 8601 format (e.g., "PT15M") then you should replace references to DurationToLongConverter with references to the new StringToDurationConverter.

  • MDA-206: The PipelineDemultiplexerStage's waitingForPipelines property previously defaulted to false, which could result in unexpected behaviour if the stage was invoked a second time without arranging to synchronise execution with the called pipelines. As a result, most deployments set waitingForPipelines to true so that the called pipelines will all complete before control is passed on from the PipelineDemultiplexerStage; this behaviour is now the default.

  • MDA-208: The enum type used to specify the SHA digest variant to be used in XMLSignatureSigningStage has been renamed from ShaVariant to SHAVariant to match our general conventions. If you refer to this type directly, your code will need to be changed. The bean property shaVariant has also been renamed to SHAVariant; in this case, the old property name is supported in this version with compile-time and run-time deprecation warnings; this migration support will be removed in V1.0.

  • MDA-219: In previous releases, the DOMResourceSourceStage tested for the existence of the supplied Resource as part of component initialization, potentially resulting in a ComponentInitializationException during initialize(). Unfortunately, this could also cause large remote resources to be fetched unnecessarily, and in addition did not guarantee that the Resource  would be accessible during normal operation. This check has been removed: now, a StageProcessingException will be thrown during stage execution instead, in the same way as was already the case for other I/O errors related to the Resource.

  • MDA-222: The contract for bean properties representing collections has changed:

    • Property setters for collection properties are now annotated as @Nonnull @NonnullElements @Unmodifiable.

      • Previously, some setters allowed a null value to act in place of an empty collection. This usage will now result in most cases in a NullPointerException.

      • Previously, some setters filtered null values out of provided collections. Again, this usage will now result in most cases in a NullPointerException.

      • Setters now guarantee not to modify the passed collection. This was previously true in practice in most cases, but is now guaranteed.

    • Most property getters for collection properties are also now annotated as @Nonnull @NonnullElements @Unmodifiable.

      • In exceptional cases, getters may be annotated as @NonnullAfterInit instead of @Nonnull. This is only done when an "empty collection" default is inappropriate for the property and would normally be accompanied by @NotEmpty on both the setter and the getter.

  • MDA-232: Previously, an invalid XPath expression provided to an XPathFilteringStage went largely unremarked: if the expression failed to compile, no filtering would be performed. If the expression could not be evaluated (for example, because it referenced a $variable) errors would be logged, and all items would be filtered out. Now:

    • An XPath expression which fails to compile will result in a ComponentInitializationException  when the stage is initialized.

    • An XPath expression which fails to evaluate will result in a StageProcessingException when the stage is executed.

  • MDA-234: The EntitiesDescriptorAssemblerStage previously allowed entities to be reordered by setting a property to an instance of an ItemOrderingStrategy sub-interface that was specific to Item<Element>. This interface has been extracted to the pipeline  package and expressed as a generic, allowing it to be reused for the new ItemOrderingStage. If you are using the orderingStrategy  property, your implementation of ItemOrderingStrategy will need to be retargeted at the new definition.