[java-identity-provider] branch master updated: IDP-1365 - rpUIContext not populated from CAS metadata

Scott Cantor cantor.2 at osu.edu
Tue Jun 25 10:09:15 EDT 2019


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

scantor pushed a commit to branch master
in repository java-identity-provider.

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=9e3688e7fc4771b3868fe04d6125f97622c90f43

The following commit(s) were added to refs/heads/master by this push:
       new  9e3688e   IDP-1365 - rpUIContext not populated from CAS metadata
9e3688e is described below

commit 9e3688e7fc4771b3868fe04d6125f97622c90f43
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jun 25 10:09:12 2019 -0400

    IDP-1365 - rpUIContext not populated from CAS metadata
    
    https://issues.shibboleth.net/jira/browse/IDP-1365
    
    Replace entity-based approach with role-based approach.
---
 .../net/shibboleth/idp/cas/service/Service.java    | 42 +++++++++----
 .../flow/impl/BuildSAMLMetadataContextAction.java  |  3 +-
 .../cas/service/impl/MetadataServiceRegistry.java  | 69 +++++++++++-----------
 .../service/impl/MetadataServiceRegistryTest.java  |  8 ++-
 .../main/resources/system/conf/services-system.xml |  2 +-
 5 files changed, 76 insertions(+), 48 deletions(-)

diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/Service.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/Service.java
index 5c3cd8a..f2da54c 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/Service.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/service/Service.java
@@ -21,6 +21,7 @@ import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -34,13 +35,10 @@ import java.security.Principal;
 public class Service implements Principal {
 
     /** Service URL. */
-    @Nonnull
-    @NotEmpty
-    private final String serviceURL;
+    @Nonnull @NotEmpty private final String serviceURL;
 
     /** Group to which service belongs. */
-    @Nullable
-    private final String serviceGroup;
+    @Nullable private final String serviceGroup;
 
     /** Proxy authorization flag. */
     private final boolean authorizedToProxy;
@@ -48,10 +46,11 @@ public class Service implements Principal {
     /** Indicates whether a service wants to receive SLO messages. */
     private final boolean singleLogoutParticipant;
 
-    /** Source of service metadata derived from a SAML entity. */
-    @Nullable
-    private transient EntityDescriptor entityDescriptor;
+    /** Source of service metadata based on SAML metadata. */
+    @Nullable private transient EntityDescriptor entityDescriptor;
 
+    /** Role for service in SAML metadata. */
+    @Nullable private transient RoleDescriptor roleDescriptor;
 
     /**
      * Creates a new service that does not participate in SLO.
@@ -127,8 +126,7 @@ public class Service implements Principal {
      *
      * @return Entity descriptor for service defined in SAML metadata, otherwise null.
      */
-    @Nullable
-    public EntityDescriptor getEntityDescriptor() {
+    @Nullable public EntityDescriptor getEntityDescriptor() {
         return entityDescriptor;
     }
 
@@ -138,7 +136,29 @@ public class Service implements Principal {
      * @param ed SAML entity descriptor.
      */
     public void setEntityDescriptor(@Nullable final EntityDescriptor ed) {
-        this.entityDescriptor = ed;
+        entityDescriptor = ed;
+    }
+    
+    /**
+     * Gets the role in the SAML metadata.
+     * 
+     * @return the role
+     * 
+     * @since 4.0.0
+     */
+    @Nullable public RoleDescriptor getRoleDescriptor() {
+        return roleDescriptor;
+    }
+    
+    /**
+     * Sets the role in the SAML metadata.
+     * 
+     * @param role the role
+     * 
+     * @since 4.0.0
+     */
+    public void setRoleDescriptor(@Nullable final RoleDescriptor role) {
+        roleDescriptor = role;
     }
 
     @Override
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java
index ecc10cb..e42b2c5 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildSAMLMetadataContextAction.java
@@ -45,7 +45,7 @@ public class BuildSAMLMetadataContextAction extends AbstractCASProtocolAction {
     protected Event doExecute(
             final @Nonnull RequestContext springRequestContext,
             final @Nonnull ProfileRequestContext profileRequestContext) {
-        final RelyingPartyContext rpCtx = profileRequestContext.getSubcontext(RelyingPartyContext.class, false);
+        final RelyingPartyContext rpCtx = profileRequestContext.getSubcontext(RelyingPartyContext.class);
         if (rpCtx == null) {
             throw new IllegalStateException("RelyingPartyContext not found");
         }
@@ -55,6 +55,7 @@ public class BuildSAMLMetadataContextAction extends AbstractCASProtocolAction {
                 ? service.getEntityDescriptor()
                 : new ServiceEntityDescriptor(service);
         mdCtx.setEntityDescriptor(entity);
+        mdCtx.setRoleDescriptor(service.getRoleDescriptor());
         rpCtx.setRelyingPartyIdContextTree(mdCtx);
 
         return null;
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistry.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistry.java
index 319de14..788f9ab 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistry.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistry.java
@@ -17,13 +17,11 @@
 
 package net.shibboleth.idp.cas.service.impl;
 
-import java.util.List;
 import java.util.function.Predicate;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import com.google.common.collect.Lists;
 import net.shibboleth.idp.cas.config.impl.AbstractProtocolConfiguration;
 import net.shibboleth.idp.cas.config.impl.LoginConfiguration;
 import net.shibboleth.idp.cas.config.impl.ProxyConfiguration;
@@ -38,10 +36,12 @@ import org.opensaml.saml.criterion.EntityRoleCriterion;
 import org.opensaml.saml.criterion.ProtocolCriterion;
 import org.opensaml.saml.criterion.StartsWithLocationCriterion;
 import org.opensaml.saml.metadata.resolver.MetadataResolver;
+import org.opensaml.saml.metadata.resolver.RoleDescriptorResolver;
 import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
 import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.saml.saml2.metadata.SingleLogoutService;
 import org.opensaml.saml.saml2.metadata.impl.AssertionConsumerServiceBuilder;
@@ -97,7 +97,7 @@ public class MetadataServiceRegistry implements ServiceRegistry {
 
     /** SAML metadata resolver. */
     @Nonnull
-    private final MetadataResolver metadataResolver;
+    private final RoleDescriptorResolver metadataResolver;
 
 
     /**
@@ -105,7 +105,7 @@ public class MetadataServiceRegistry implements ServiceRegistry {
      *
      * @param resolver SAML metadata resolver.
      */
-    public MetadataServiceRegistry(@Nonnull @ParameterName(name="resolver") final MetadataResolver resolver) {
+    public MetadataServiceRegistry(@Nonnull @ParameterName(name="resolver") final RoleDescriptorResolver resolver) {
         metadataResolver = resolver;
     }
 
@@ -113,11 +113,11 @@ public class MetadataServiceRegistry implements ServiceRegistry {
     @Override
     public Service lookup(final @Nonnull String serviceURL) {
         try {
-            final List<EntityDescriptor> entities = Lists.newArrayList(metadataResolver.resolve(criteria(serviceURL)));
-            if (entities.size() > 1) {
-                throw new ResolverException("Multiple results found");
-            } else if (entities.size() == 1) {
-                return create(serviceURL, entities.get(0));
+            final RoleDescriptor role = metadataResolver.resolveSingle(criteria(serviceURL));
+            if (role instanceof SPSSODescriptor) {
+                return create(serviceURL, (SPSSODescriptor) role);
+            } else {
+                throw new ResolverException("No compatible role resolved");
             }
         } catch (final ResolverException e) {
             log.warn("Metadata resolution failed for {}", serviceURL, e);
@@ -145,53 +145,56 @@ public class MetadataServiceRegistry implements ServiceRegistry {
     }
 
     /**
-     * Create a CAS {@link Service} from an input service URL and the matching {@link EntityDescriptor} that was
+     * Create a CAS {@link Service} from an input service URL and the matching {@link RoleDescriptor} that was
      * resolved from the metadata source.
      *
      * @param serviceURL CAS service URL.
-     * @param entity Entity resolved from metadata.
+     * @param role resolved from metadata.
      *
      * @return CAS service created from inputs.
      */
     @Nonnull
-    protected Service create(@Nonnull final String serviceURL, @Nonnull final EntityDescriptor entity) {
+    protected Service create(@Nonnull final String serviceURL, @Nonnull final SPSSODescriptor role) {
+        
+        final EntityDescriptor entity = (EntityDescriptor) role.getParent();
         final XMLObject parent = entity.getParent();
+                
         final Service service = new Service(
                 serviceURL,
                 parent instanceof EntitiesDescriptor ? ((EntitiesDescriptor) parent).getName() : "unknown",
-                isAuthorizedToProxy(entity),
-                hasSingleLogoutService(entity));
+                isAuthorizedToProxy(role),
+                hasSingleLogoutService(role));
+        service.setRoleDescriptor(role);
         service.setEntityDescriptor(entity);
         return service;
     }
 
-    /** Does the {@link EntityDescriptor} have a {@link MetadataServiceRegistry#PROXY_BINDING} acs. 
-     * @param entity  what to look at
-     * @return Whether is is authorized to proxy
+    /**
+     * Checks if the {@link EntityDescriptor} have a {@link MetadataServiceRegistry#PROXY_BINDING} acs.
+     *  
+     * @param role  what to look at
+     * 
+     * @return whether is is authorized to proxy
      */
-    private boolean isAuthorizedToProxy(@Nonnull final EntityDescriptor entity) {
-        final SPSSODescriptor descriptor = entity.getSPSSODescriptor(AbstractProtocolConfiguration.PROTOCOL_URI);
-        if (descriptor != null) {
-            for (final AssertionConsumerService acs : descriptor.getAssertionConsumerServices()) {
-                if (PROXY_BINDING.equals(acs.getBinding())) {
-                    return true;
-                }
+    private boolean isAuthorizedToProxy(@Nonnull final SPSSODescriptor role) {
+        for (final AssertionConsumerService acs : role.getAssertionConsumerServices()) {
+            if (PROXY_BINDING.equals(acs.getBinding())) {
+                return true;
             }
         }
         return false;
     }
 
-    /** Does the {@link EntityDescriptor} has an SLO endpoint.
-     * @param entity what to look at
+    /** Checks if the {@link EntityDescriptor} has an SLO endpoint.
+     * 
+     * @param role what to look at
+     * 
      * @return whether it has an SLO endpoint
      */
-    private boolean hasSingleLogoutService(@Nonnull final EntityDescriptor entity) {
-        final SPSSODescriptor descriptor = entity.getSPSSODescriptor(AbstractProtocolConfiguration.PROTOCOL_URI);
-        if (descriptor != null) {
-            for (final Endpoint endpoint : descriptor.getEndpoints(SingleLogoutService.DEFAULT_ELEMENT_NAME)) {
-                if (LOGOUT_BINDING.equals(endpoint.getBinding()) && LOGOUT_LOCATION.equals(endpoint.getLocation())) {
-                    return true;
-                }
+    private boolean hasSingleLogoutService(@Nonnull final SPSSODescriptor role) {
+        for (final Endpoint endpoint : role.getEndpoints(SingleLogoutService.DEFAULT_ELEMENT_NAME)) {
+            if (LOGOUT_BINDING.equals(endpoint.getBinding()) && LOGOUT_LOCATION.equals(endpoint.getLocation())) {
+                return true;
             }
         }
         return false;
diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistryTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistryTest.java
index a87eb97..1538442 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistryTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/service/impl/MetadataServiceRegistryTest.java
@@ -23,10 +23,12 @@ import java.util.Timer;
 
 import net.shibboleth.ext.spring.resource.ResourceHelper;
 import net.shibboleth.idp.cas.service.Service;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.resource.Resource;
 import org.opensaml.core.config.InitializationException;
 import org.opensaml.core.config.InitializationService;
 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
+import org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver;
 import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver;
 import org.opensaml.saml.metadata.resolver.index.MetadataIndex;
 import org.opensaml.saml.metadata.resolver.index.impl.EndpointMetadataIndex;
@@ -93,8 +95,10 @@ public class MetadataServiceRegistryTest {
     }
 
     @Test(dataProvider = "parameters")
-    public void testLookup(final String serviceURL, final Service expected) {
-        final MetadataServiceRegistry registry = new MetadataServiceRegistry(metadataResolver);
+    public void testLookup(final String serviceURL, final Service expected) throws ComponentInitializationException {
+        final PredicateRoleDescriptorResolver wrapper = new PredicateRoleDescriptorResolver(metadataResolver);
+        wrapper.initialize();
+        final MetadataServiceRegistry registry = new MetadataServiceRegistry(wrapper);
         final Service actual = registry.lookup(serviceURL);
         if (expected == null) {
             assertNull(actual);
diff --git a/idp-conf/src/main/resources/system/conf/services-system.xml b/idp-conf/src/main/resources/system/conf/services-system.xml
index 4fed0b6..1156544 100644
--- a/idp-conf/src/main/resources/system/conf/services-system.xml
+++ b/idp-conf/src/main/resources/system/conf/services-system.xml
@@ -186,6 +186,6 @@
 
     <bean id="shibboleth.CASMetadataServiceRegistry"
           class="net.shibboleth.idp.cas.service.impl.MetadataServiceRegistry"
-          c:resolver-ref="shibboleth.MetadataResolver" />
+          c:resolver-ref="shibboleth.RoleDescriptorResolver" />
           
  </beans>

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


More information about the commits mailing list