[java-identity-provider] branch master updated: IDP-701 Use attribute authority for CAS proxy.

Marvin S. Addison marvin.addison at gmail.com
Thu Jun 21 08:09:06 EDT 2018


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

serac 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=077dad07caeea90147f5feaa88f8ee4f6fa34fe7

The following commit(s) were added to refs/heads/master by this push:
       new  077dad0   IDP-701 Use attribute authority for CAS proxy.
077dad0 is described below

commit 077dad07caeea90147f5feaa88f8ee4f6fa34fe7
Author: Marvin S. Addison <serac at vt.edu>
AuthorDate: Thu Jun 21 08:02:32 2018 -0400

    IDP-701 Use attribute authority for CAS proxy.
    
    Let the presence of an AttributeAuthorityDescriptor that advertises support
    for https://www.apereo.org/cas/protocol indicate CAS proxy authorization.
    In the future any signing certificates will be added as explicit trust
    material for use in proxy callback validation, which would be analogous to
    the mechanics of TLS trust for back-channel attribute queries.
---
 .../cas/service/impl/MetadataServiceRegistry.java  | 50 ++++++++++++----------
 .../test/resources/metadata/cas-test-metadata.xml  | 39 +++++++++--------
 2 files changed, 48 insertions(+), 41 deletions(-)

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 562247f..31fe5d3 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,11 +17,7 @@
 
 package net.shibboleth.idp.cas.service.impl;
 
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -29,6 +25,7 @@ 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;
 import net.shibboleth.idp.cas.service.Service;
 import net.shibboleth.idp.cas.service.ServiceRegistry;
 import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
@@ -40,14 +37,14 @@ import org.opensaml.saml.criterion.ProtocolCriterion;
 import org.opensaml.saml.criterion.StartsWithLocationCriterion;
 import org.opensaml.saml.metadata.resolver.MetadataResolver;
 import org.opensaml.saml.saml2.metadata.AssertionConsumerService;
+import org.opensaml.saml.saml2.metadata.AttributeAuthorityDescriptor;
+import org.opensaml.saml.saml2.metadata.AttributeService;
 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.KeyDescriptor;
 import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.opensaml.saml.saml2.metadata.SingleLogoutService;
 import org.opensaml.saml.saml2.metadata.impl.AssertionConsumerServiceBuilder;
-import org.opensaml.xmlsec.keyinfo.KeyInfoSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,17 +64,28 @@ import org.slf4j.LoggerFactory;
  *
  * If a single match is found, it is converted to a {@link Service} and returned; if more than result is found, a
  * {@link ResolverException} is raised, otherwise null is returned.
+ * <p>
+ * The presence of an <code>AttributeAuthorityDescriptor</code> element that advertises protocol support for
+ * <code>{@value AbstractProtocolConfiguration#PROTOCOL_URI}</code> signals a CAS proxy endpoint. If at least one
+ * <code>AttributeService</code> with a binding of <code>{@value #PROXY_BINDING}</code> is defined, the service is
+ * authorized to request proxy granting tickets.
+ * <p>
+ * See the <a href="https://wiki.shibboleth.net/confluence/x/BQfKAg">SAML metadata profile for CAS</a> for further
+ * details.
  *
  * @author Marvin S. Addison
  */
 public class MetadataServiceRegistry implements ServiceRegistry {
 
     /** URI identifying an ACS endpoint that requests CAS service tickets. */
-    public static final String LOGIN_BINDING = LoginConfiguration.PROTOCOL_URI;
+    public static final String LOGIN_BINDING = LoginConfiguration.PROFILE_ID;
 
     /** URI identifying a CAS SLO endpoint. */
     public static final String LOGOUT_BINDING = AbstractProtocolConfiguration.PROTOCOL_URI + "/logout";
 
+    /** URI identifying a CAS proxy callback endoint. */
+    public static final String PROXY_BINDING = ProxyConfiguration.PROFILE_ID;
+
     /** Class logger. */
     private final Logger log = LoggerFactory.getLogger(MetadataServiceRegistry.class);
 
@@ -142,34 +150,30 @@ public class MetadataServiceRegistry implements ServiceRegistry {
     @Nonnull
     protected Service create(@Nonnull final String serviceURL, @Nonnull final EntityDescriptor entity) {
         final XMLObject parent = entity.getParent();
-        final SPSSODescriptor descriptor = entity.getSPSSODescriptor(AbstractProtocolConfiguration.PROTOCOL_URI);
-        if (descriptor == null) {
-            throw new IllegalStateException("SPSSODescriptor element not found for entity " + entity.getEntityID());
-        }
         final Service service = new Service(
                 serviceURL,
                 parent instanceof EntitiesDescriptor ? ((EntitiesDescriptor) parent).getName() : "unknown",
-                isAuthorizedToProxy(descriptor),
-                hasSingleLogoutService(descriptor));
+                isAuthorizedToProxy(entity),
+                hasSingleLogoutService(entity));
         service.setEntityDescriptor(entity);
         return service;
     }
 
-    private boolean isAuthorizedToProxy(@Nonnull final SPSSODescriptor descriptor) {
-        final Set<X509Certificate> certs = new HashSet<>();
-        for (KeyDescriptor kd : descriptor.getKeyDescriptors()) {
-            if (kd.getKeyInfo() != null) {
-                try {
-                    certs.addAll(KeyInfoSupport.getCertificates(kd.getKeyInfo()));
-                } catch (CertificateException e) {
-                    throw new RuntimeException("Error decoding metadata certificate", e);
+    private boolean isAuthorizedToProxy(@Nonnull final EntityDescriptor entity) {
+        final AttributeAuthorityDescriptor descriptor = entity.getAttributeAuthorityDescriptor(
+                AbstractProtocolConfiguration.PROTOCOL_URI);
+        if (descriptor != null) {
+            for (AttributeService as : descriptor.getAttributeServices()) {
+                if (PROXY_BINDING.equals(as.getBinding())) {
+                    return true;
                 }
             }
         }
-        return certs.size() > 0;
+        return false;
     }
 
-    private boolean hasSingleLogoutService(@Nonnull final SPSSODescriptor descriptor) {
+    private boolean hasSingleLogoutService(@Nonnull final EntityDescriptor entity) {
+        final SPSSODescriptor descriptor = entity.getSPSSODescriptor(AbstractProtocolConfiguration.PROTOCOL_URI);
         if (descriptor != null) {
             for (Endpoint endpoint : descriptor.getEndpoints(SingleLogoutService.DEFAULT_ELEMENT_NAME)) {
                 if (LOGOUT_BINDING.equals(endpoint.getBinding())) {
diff --git a/idp-cas-impl/src/test/resources/metadata/cas-test-metadata.xml b/idp-cas-impl/src/test/resources/metadata/cas-test-metadata.xml
index 2a9a76a..aca6004 100644
--- a/idp-cas-impl/src/test/resources/metadata/cas-test-metadata.xml
+++ b/idp-cas-impl/src/test/resources/metadata/cas-test-metadata.xml
@@ -2,9 +2,7 @@
         Name="urn:mace:example.org"
         xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
         xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
-        xmlns:mdattr="urn:oasis:names:tc:SAML:metadata:attribute"
         xmlns:mdui="urn:oasis:names:tc:SAML:metadata:ui"
-        xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
         validUntil="2050-12-31T23:59:59Z">
 
     <!--
@@ -125,6 +123,23 @@
        -->
     <EntityDescriptor entityID="https://alpha.example.org/">
         <SPSSODescriptor protocolSupportEnumeration="https://www.apereo.org/cas/protocol">
+            <AssertionConsumerService
+                    Binding="https://www.apereo.org/cas/protocol/login"
+                    Location="https://alpha.example.org/"
+                    index="1"/>
+            <AssertionConsumerService
+                    Binding="https://www.apereo.org/cas/protocol/login"
+                    Location="https://alpha.dev.example.org/"
+                    index="2"/>
+            <AssertionConsumerService
+                    Binding="https://www.apereo.org/cas/protocol/login"
+                    Location="https://alpha.test.example.org/"
+                    index="3"/>
+            <SingleLogoutService
+                    Binding="https://www.apereo.org/cas/protocol/logout"
+                    Location="https://not.used.invalid/"/>
+        </SPSSODescriptor>
+        <AttributeAuthorityDescriptor protocolSupportEnumeration="https://www.apereo.org/cas/protocol">
             <KeyDescriptor use="signing">
                 <ds:KeyInfo>
                     <ds:X509Data>
@@ -195,22 +210,10 @@
                     </ds:X509Data>
                 </ds:KeyInfo>
             </KeyDescriptor>
-            <AssertionConsumerService
-                    Binding="https://www.apereo.org/cas/protocol/login"
-                    Location="https://alpha.example.org/"
-                    index="1"/>
-            <AssertionConsumerService
-                    Binding="https://www.apereo.org/cas/protocol/login"
-                    Location="https://alpha.dev.example.org/"
-                    index="2"/>
-            <AssertionConsumerService
-                    Binding="https://www.apereo.org/cas/protocol/login"
-                    Location="https://alpha.test.example.org/"
-                    index="3"/>
-            <SingleLogoutService
-                    Binding="https://www.apereo.org/cas/protocol/logout"
-                    Location="https://not.used.invalid/"/>
-        </SPSSODescriptor>
+            <AttributeService
+                    Binding="https://www.apereo.org/cas/protocol/proxy"
+                    Location="https://alpha.example.org/proxy_receptor" />
+        </AttributeAuthorityDescriptor>
     </EntityDescriptor>
 
     <!--

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


More information about the commits mailing list