[java-oidc-common] 02/05: Stub out generic metadata filtering and validation

Phil Smart philip.smart at jisc.ac.uk
Thu Oct 14 16:48:21 UTC 2021


This is an automated email from the git hooks/post-receive script.

philsmart pushed a commit to branch main
in repository java-oidc-common.

View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=f2fcce67e9251069dea3947081f44a3f3bd55b88

commit f2fcce67e9251069dea3947081f44a3f3bd55b88
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Thu Sep 2 16:40:42 2021 +0100

    Stub out generic metadata filtering and validation
    
    Needs thinking about.
---
 .../oidc/metadata/filter/MetadataSource.java       |  56 +++++++++++
 ...bstractDynamicOIDCProviderMetadataResolver.java | 103 ++++++++++++++++++++-
 .../impl/AbstractOIDCMetadataResolver.java         |   9 ++
 .../HTTPProviderConfigurationMetadataResolver.java |  35 +++++++
 4 files changed, 201 insertions(+), 2 deletions(-)

diff --git a/oidc-common-metadata-api/src/main/java/net/shibboleth/oidc/metadata/filter/MetadataSource.java b/oidc-common-metadata-api/src/main/java/net/shibboleth/oidc/metadata/filter/MetadataSource.java
new file mode 100644
index 0000000..7a6f03d
--- /dev/null
+++ b/oidc-common-metadata-api/src/main/java/net/shibboleth/oidc/metadata/filter/MetadataSource.java
@@ -0,0 +1,56 @@
+package net.shibboleth.oidc.metadata.filter;
+
+import javax.annotation.Nullable;
+
+import net.shibboleth.oidc.metadata.filter.MetadataFilterContext.Data;
+
+/**
+ * Data object for {@link MetadataFilterContext} intended to hold information about the source of the
+ * metadata currently being processed.
+
+ */
+public class MetadataSource implements Data {
+
+    /** An identifier for the source of the metadata, typically the resolver ID. */
+    @Nullable private String sourceId;
+
+    /** Flag indicating whether the metadata source is trusted. */
+    private boolean trusted;
+    
+    /**
+     * Get identifier of the metadata source.
+     * 
+     * @return source identifier
+     */
+    @Nullable public String getSourceId() {
+        return sourceId;
+    }
+    
+    /**
+     * Set identifier of the metadata source. 
+     * 
+     * @param id source identifier
+     */
+    public void setSourceId(@Nullable final String id) {
+        sourceId = id;
+    }
+
+    /**
+     * Get whether the metadata source is trusted.
+     *
+     * @return true if trusted, false if not
+     */
+    public boolean isTrusted() {
+        return trusted;
+    }
+
+    /**
+     * Set whether the metadata source is trusted.
+     *
+     * @param flag true if trusted, false if not
+     */
+    public void setTrusted(final boolean flag) {
+        this.trusted = flag;
+    }
+
+}
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractDynamicOIDCProviderMetadataResolver.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractDynamicOIDCProviderMetadataResolver.java
index 9e39084..4a7709c 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractDynamicOIDCProviderMetadataResolver.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractDynamicOIDCProviderMetadataResolver.java
@@ -11,6 +11,7 @@ import java.util.concurrent.locks.Lock;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import org.opensaml.core.xml.XMLObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -20,7 +21,8 @@ import net.shibboleth.oidc.metadata.DynamicBackingStore;
 import net.shibboleth.oidc.metadata.DynamicOIDCProviderMetadataResolver;
 import net.shibboleth.oidc.metadata.MetadataManagementData;
 import net.shibboleth.oidc.metadata.filter.FilterException;
-import net.shibboleth.oidc.metadata.filter.MetadataFilter;
+import net.shibboleth.oidc.metadata.filter.MetadataFilterContext;
+import net.shibboleth.oidc.metadata.filter.MetadataSource;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
@@ -234,6 +236,15 @@ public abstract class AbstractDynamicOIDCProviderMetadataResolver<MetadataIdenti
         ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
         ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
         
+        // Find identifier from criteria (impl specific)
+        
+        // Lock and check cache for metadata relating to entity
+        // // If exists check it should not be refershed. 
+        
+        // if not in cache or requires refresh lookup from source.
+        
+        // Filter candidates
+        
         //final Context contextResolve = MetricsSupport.startTimer(timerResolve);
         try {
             Iterable<MetadataType> candidates = null;
@@ -374,7 +385,18 @@ public abstract class AbstractDynamicOIDCProviderMetadataResolver<MetadataIdenti
                     throws FilterException, ResolverException {
         
         
-        // TODO filter metadata if required and configured.
+        // Filter metadata if required and configured.
+        final MetadataType filteredMetadata = filterMetadata(prepareForFiltering(metadata));
+        if (filteredMetadata == null) {
+            log.info("{} Metadata filtering process produced a null document, resulting in an empty data set", 
+                    getLogPrefix());
+            finalizeMetadataProcessing(metadata);
+            return;
+        }
+        
+        if (!isNewMetadataValid(filteredMetadata, expectedIdentifier)) {
+            return;
+        }
         
         // determine identifier
         final MetadataIdentifier identifier = extractIdentifier(metadata);
@@ -412,12 +434,89 @@ public abstract class AbstractDynamicOIDCProviderMetadataResolver<MetadataIdenti
         mgmtData.setRefreshTriggerTime(computeRefreshTriggerTime(mgmtData.getExpirationTime(), now));
         log.debug("{} Computed refresh trigger time: {}", getLogPrefix(), mgmtData.getRefreshTriggerTime());
         
+        log.info("{} Successfully loaded new EntityDescriptor with entityID '{}' from {}",
+                getLogPrefix(), identifier, 
+                fromPersistentCache ? "persistent cache" : "origin source");
+        
+        //finalize processing of both the filtered and original metadata.
+        finalizeMetadataProcessing(filteredMetadata);
+        finalizeMetadataProcessing(metadata);
+        
         //TODO log the new metadata expiration
         
         //TODO  save metadata to persistent cache if enabled.
         
     }
     
+    /**
+     * Check the metadata is valid e.g. is the correct type. Is implementation specific. 
+     * 
+     * @param metadata the metadata to check.
+     * @param expectedIdentifier the expected identifier of the metadata.
+     * 
+     * @return true iff the metadata is valid, false otherwise.
+     * 
+     * @throws FilterException if there is a fatal error validating the metadata.
+     */
+    @Nonnull protected abstract boolean isNewMetadataValid(@Nonnull final MetadataType metadata,
+            @Nonnull final MetadataIdentifier expectedIdentifier) throws ResolverException;
+
+    /**
+     * Prepare the object for filtering. This is implementation specific.
+     * 
+     * @param input the metadata on which to operate
+     * 
+     * @return the metadata instance to be filtered
+     */
+    @Nonnull protected abstract MetadataType prepareForFiltering(@Nonnull final MetadataType input);
+    
+    /**
+    * Finalize the metadata object after processing. This is implementation specific.
+    * 
+    * @param input the metadata on which to operate
+    * 
+    * @return the metadata instance to be filtered
+    */
+   @Nonnull protected abstract void finalizeMetadataProcessing(@Nonnull final MetadataType input);
+    
+    /**
+     * Filters the given metadata.
+     * 
+     * @param metadata the metadata to be filtered
+     * 
+     * @return the filtered metadata
+     * 
+     * @throws FilterException thrown if there is an error filtering the metadata
+     */
+    @Nullable protected MetadataType filterMetadata(@Nullable final MetadataType metadata) throws FilterException {
+        if (getMetadataFilter() != null) {
+            log.debug("{} Applying metadata filter", getLogPrefix());
+            return getMetadataFilter().filter(metadata, newFilterContext());
+        }
+        return metadata;
+    }
+    
+    /**
+     * Get a new instance of {@link MetadataFilterContext} to be used when filtering metadata.
+     *
+     * <p>
+     * This default implementation will just return an empty context.  Subclasses would override
+     * to add contextual info specific to the implementation.
+     * </p>
+     *
+     * @return the new filter context instance
+     */
+    @Nonnull protected MetadataFilterContext newFilterContext() {
+        
+        final MetadataSource source = new MetadataSource();
+        source.setSourceId(getId());
+
+        final MetadataFilterContext context = new MetadataFilterContext();
+        context.add(source);
+        
+        return context;
+    }
+    
     /**
      * Compute the effective expiration time for the specified metadata.
      * 
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java
index 8d95ef0..6a266c7 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/AbstractOIDCMetadataResolver.java
@@ -68,6 +68,15 @@ public abstract class AbstractOIDCMetadataResolver<MetadataIdentifier, MetadataT
         return logPrefix;
     }
     
+    /**
+     * Gets the metadata filter applied to the metadata.
+     * 
+     * @return the metadata filter applied to the metadata
+     */
+    @Nullable public MetadataFilter<MetadataType> getMetadataFilter() {
+        return mdFilter;
+    }
+    
     
     /**
      * Set the entity backing store currently in use by the metadata resolver.
diff --git a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/HTTPProviderConfigurationMetadataResolver.java b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/HTTPProviderConfigurationMetadataResolver.java
index 4c6eff5..4345015 100644
--- a/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/HTTPProviderConfigurationMetadataResolver.java
+++ b/oidc-common-metadata-impl/src/main/java/net/shibboleth/oidc/metadata/impl/HTTPProviderConfigurationMetadataResolver.java
@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.time.Instant;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.function.BiFunction;
 
@@ -234,6 +235,40 @@ public class HTTPProviderConfigurationMetadataResolver
         
     }
 
+    @Override
+    @Nonnull protected boolean isNewMetadataValid(@Nonnull final OIDCProviderMetadata metadata,
+            @Nonnull final Issuer expectedIdentifier) throws ResolverException {
+        
+        if (!Objects.equals(metadata.getIssuer(), expectedIdentifier)) {
+            log.warn("{} New metadata's issuer '{}' does not match expected issuer '{}', will not process", 
+                    getLogPrefix(), metadata.getIssuer(), expectedIdentifier);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * No-op method for this resolver.
+     */
+    @Override
+    @Nonnull protected OIDCProviderMetadata prepareForFiltering(@Nonnull final  OIDCProviderMetadata input) {
+        //do nothing, just return
+        return input;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * No-op method for this resolver.
+     */
+    @Override
+    @Nonnull protected void finalizeMetadataProcessing(@Nonnull final  OIDCProviderMetadata input) {
+        //do nothing, just return
+        return;       
+    }
+
    
 
 }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list