Implementation of {@link KeyInfoCredentialResolver} which resolves credentials based on a {@link KeyInfo} elementusing a configured list of {@link KeyInfoProvider}'s and optional post-processing hooks.
The majority of the processing of the KeyInfo and extraction of {@link Credential}'s from the KeyInfo is handled by instances of {@link KeyInfoProvider}. An ordered list of KeyInfoProviders must be supplied to the resolver when it is constructed.
This resolver requires a {@link KeyInfoCriteria} to be supplied as the resolution criteria. It is permissible,however, for the criteria's KeyInfo data object to be null. This allows for more convenient processing logic, for example, in cases when a parent element allows an optional KeyInfo and when in fact a given instance does not contain one. Specialized subclasses of this resolver may still attempt to return credentials in an implementation or context-specific manner, as described below.
Processing of the supplied KeyInfo element proceeds as follows:
- A {@link KeyInfoResolutionContext} is instantiated. This resolution context is used to hold state shared amongstall the providers and processing hooks which run within the resolver.
- This resolution context is initialized and populated with the actual KeyInfo object being processed as well as the values of any {@link KeyName} child elements present.
- An attempt is then made to resolve a credential from any {@link KeyValue} child elements as described for{@link #resolveKeyValue(KeyInfoResolutionContext,CriteriaSet,List)} If a credential is so resolved, its key willalso be placed in the resolution context
- The remaining (non-KeyValue) children are then processed in document order. Each child element is processed by the registered providers in provider list order. The credential or credentials resolved by the first provider to successfully do so are added to the effective set of credentials returned by the resolver, and processing of that child element terminates. Processing continues with the next child element.
- At this point all KeyInfo children have been processed. If the effective set of credentials to return is empty, and if a key was resolved from a KeyValue element and is available in the resolution context, a basic credential is built with that key and is added to the effective set. Since the KeyInfo may have a plain KeyValue representation of the key represented by the KeyInfo, in addition to a more specific key type/container (and hence credential) representation, this technique avoids the unnecessary return of duplicate keys, returning only the more specific credential representation of the key.
- A post-processing hook is then called: {@link #postProcess(KeyInfoResolutionContext,CriteriaSet,List)}. The default implementation is a no-op. This is an extension point by which subclasses may implement custom post-processing of the effective credential set to be returned. One example use case is when the KeyInfo being processed represents the public aspects (e.g. public key, or a key name or other identifier) of an encryption key belonging to the resolving entity. The resolved public keys and other resolution context information may be used to further resolve the credential or credentials containing the associated decryption key (i.e. a private or symmetric key). For an example of such an implementation, see {@link LocalKeyInfoCredentialResolver}
- Finally, if no credentials have been otherwise resolved, a final post-processing hook is called: {@link #postProcessEmptyCredentials(KeyInfoResolutionContext,CriteriaSet,List)}. The default implementation is a no-op. This is an extension point by which subclasses may implement custom logic to resolve credentials in an implementation or context-specific manner, if no other mechanism has succeeded. Example usages might be to return a default set of credentials, or to use non-KeyInfo-derived criteria or contextual information to determine the credential or credentials to return.