To support Attribute Push, scan the POST Response for attributes and if any are prese...
authorgilbert <gilbert@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 21 Jul 2005 14:59:27 +0000 (14:59 +0000)
committergilbert <gilbert@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 21 Jul 2005 14:59:27 +0000 (14:59 +0000)
Some cleanup of the attribute processing code.

git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@1742 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/serviceprovider/AssertionConsumerServlet.java
src/edu/internet2/middleware/shibboleth/serviceprovider/AttributeRequestor.java
src/edu/internet2/middleware/shibboleth/serviceprovider/ShibBinding.java

index 91c127c..f9aace3 100644 (file)
@@ -60,10 +60,13 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.log4j.Logger;
+import org.opensaml.SAMLAssertion;
+import org.opensaml.SAMLAttributeStatement;
 import org.opensaml.SAMLAudienceRestrictionCondition;
 import org.opensaml.SAMLCondition;
 import org.opensaml.SAMLException;
 import org.opensaml.SAMLResponse;
+import org.opensaml.SAMLStatement;
 import org.opensaml.SAMLBrowserProfile.BrowserProfileResponse;
 
 import x0.maceShibbolethTargetConfig1.ApplicationDocument.Application;
@@ -299,12 +302,42 @@ public class AssertionConsumerServlet extends HttpServlet {
         // Very agressive attribute fetch rule 
         // Get the Attributes immediately! [good for debugging]
         Session session = sessionManager.findSession(sessionid, applicationId);
+        
+        checkForAttributePush(samldata, session);
+        
         AttributeRequestor.fetchAttributes(session);
 
         return sessionid;
     }
 
 
+    /**
+     * Scan the POST data for Attribute Assertions. If any are found,
+     * then attributes have been pushed and we don't need to go to 
+     * the AA to get them. 
+     * @param samldata The BrowserProfileResponse containing the SAMLResponse
+     * @param session The Session just created
+     */
+    private static void checkForAttributePush(BrowserProfileResponse samldata, Session session) {
+        SAMLResponse samlresponse = samldata.response;
+        Iterator assertions = samlresponse.getAssertions();
+        while (assertions.hasNext()) {
+            SAMLAssertion assertion = (SAMLAssertion) assertions.next();
+            Iterator statements = assertion.getStatements();
+            while (statements.hasNext()) {
+                SAMLStatement statement = (SAMLStatement) statements.next();
+                if (statement instanceof SAMLAttributeStatement) {
+                    session.setAttributeResponse(samlresponse);
+                    // Note, the Attribute Statements have not been checked for 
+                    // AAP or Signatures. AttributeRequestor will bypass calling
+                    // the AA and will reprocess the POST Response for Attributes.
+                    return;
+                }
+            }
+        }
+    }
+
+
 
     protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1)
        throws ServletException, IOException {
index f49b81b..62e6822 100644 (file)
@@ -115,14 +115,19 @@ public class AttributeRequestor {
                ServiceProviderConfig config = context.getServiceProviderConfig();
                ApplicationInfo appinfo = config.getApplication(session.getApplicationId());
                
-               // The Entity name was fed by by ShibPOSTProfile.accept(). Look it up now.
+        SAMLResponse response = session.getAttributeResponse();
+
+        // The Entity name was fed by by ShibPOSTProfile.accept(). Look it up in the
+        // Metadata now and return the Entity object.
                EntityDescriptor entity = appinfo.lookup(session.getEntityId());
                if (entity==null) {
                        log.error("Entity(Site) deleted from Metadata since authentication POST received: "+session.getEntityId());
                        return false;
                }
+        
                SAMLRequest request = null;
                
+        // Find the Shibboleth protocol AA Role configured in the Metadat for this Entity. 
                AttributeAuthorityDescriptor aa = 
                    entity.getAttributeAuthorityDescriptor(XML.SAML11_PROTOCOL_ENUM); // throws MetadataException
                if (aa==null) {
@@ -130,60 +135,65 @@ public class AttributeRequestor {
                    return false;
                }
                
-               // Build the Attribute Query 
-               SAMLAttributeQuery query = null;
-               SAMLSubject subject;
-               try {
-                       SAMLAuthenticationStatement authenticationStatement = session.getAuthenticationStatement();
-                       if (authenticationStatement==null) {
-                           log.error("Session contains no Authentication Statement." );
-                           return false;
-                       }
-                       SAMLSubject subject2 = authenticationStatement.getSubject();
-                       if (subject2==null) {
-                           log.error("Session Authentication Statement contains no Subject." );
-                           return false;
-                       }
-                       subject = (SAMLSubject) subject2.clone();
-               } catch (Exception e) {
-                   log.error("Unable to generate the query SAMLSubject from the Authenticaiton." );
-                   return false;
-               }
-               log.debug("Subject (Handle) is "+subject.getNameIdentifier());
-               Collection attributeDesignators = appinfo.getAttributeDesignators();
-               try {
-            query = 
-                new SAMLAttributeQuery(
-                       subject,                 // Subject (i.e. Handle) from authentication
-                       appinfo.getProviderId(),  // SP Entity name
-                       attributeDesignators // Attributes to request, null for everything
-                       );
-
-            // Wrap the Query in a request
-            request = new SAMLRequest(query);
-        } catch (SAMLException e) {
-            log.error("AttributeRequestor unable to build SAML Query for Session "+session.getKey());
-            return false;
-        }
-               
-        String credentialId = appinfo.getCredentialIdForEntity(entity);
-        if (credentialId!=null)
-            possiblySignRequest(config.getCredentials(), request, credentialId);
-               
-               // ShibBinding will extract URLs from the Metadata and build
-               // parameters so SAML can create the session. It also interfaces
-               // to Trust to verify that any signed objects have trusted signatures.
-               SAMLResponse response = null;
-               try {
-            ShibBinding binding = new ShibBinding(session.getApplicationId());
-                       response = binding.send(request,aa,null,null,appinfo);
-               } catch (SAMLException e) {;} // response will be null
                if (response==null) {
-                       log.error("AttributeRequestor Query to remote AA returned no response from "+session.getEntityId());
-                       return false;
+                   // Build the Attribute Query 
+                   SAMLAttributeQuery query = null;
+                   SAMLSubject subject;
+                   try {
+                       // Get the POST data from the Session. It has the Subject and its source.
+                       SAMLAuthenticationStatement authenticationStatement = session.getAuthenticationStatement();
+                       if (authenticationStatement==null) {
+                           log.error("Session contains no Authentication Statement." );
+                           return false;
+                       }
+                       SAMLSubject subject2 = authenticationStatement.getSubject();
+                       if (subject2==null) {
+                           log.error("Session Authentication Statement contains no Subject." );
+                           return false;
+                       }
+                       subject = (SAMLSubject) subject2.clone();
+                   } catch (Exception e) {
+                       log.error("Unable to generate the query SAMLSubject from the Authenticaiton." );
+                       return false;
+                   }
+                   log.debug("Subject (Handle) is "+subject.getNameIdentifier());
+                   
+                   
+                   
+                   
+                   Collection attributeDesignators = appinfo.getAttributeDesignators();
+                   try {
+                       query = 
+                           new SAMLAttributeQuery(
+                                   subject,                     // Subject (i.e. Handle) from authentication
+                                   appinfo.getProviderId(),  // SP Entity name
+                                   attributeDesignators // Attributes to request, null for everything
+                           );
+                       
+                       // Wrap the Query in a request
+                       request = new SAMLRequest(query);
+                   } catch (SAMLException e) {
+                       log.error("AttributeRequestor unable to build SAML Query for Session "+session.getKey());
+                       return false;
+                   }
+                   
+                   String credentialId = appinfo.getCredentialIdForEntity(entity);
+                   if (credentialId!=null)
+                       possiblySignRequest(config.getCredentials(), request, credentialId);
+                   
+                   // ShibBinding will extract URLs from the Metadata and build
+                   // parameters so SAML can create the session. It also interfaces
+                   // to Trust to verify that any signed objects have trusted signatures.
+                   try {
+                       ShibBinding binding = new ShibBinding(session.getApplicationId());
+                       response = binding.send(request,aa,null,null,appinfo);
+                   } catch (SAMLException e) {;} // response will be null
+                   if (response==null) {
+                       log.error("AttributeRequestor Query to remote AA returned no response from "+session.getEntityId());
+                       return false;
+                   }
                }
                
-               
                // Check each assertion in the response.
         int acount = 0;
                Iterator assertions = response.getAssertions();
index f95ca89..25f751a 100644 (file)
@@ -176,24 +176,29 @@ public class ShibBinding {
        }
 
        /**
-        * Validate signatures in response against the Trust configuration.
+        * Given a SAMLResponse, check the Response itself and every Assertion it 
+     * contains for a digital signature. If signed, call Trust to verify the
+     * signature against the configured Certificates for this Role in the Metadata.
         * 
         * @param role     OriginSite
         * @param appinfo  Application data
         * @param resp     SAML response
         * @throws TrustException on failure
         */
-       private void 
+       public static void 
        validateResponseSignatures(
                        AttributeAuthorityDescriptor role, 
                        ApplicationInfo appinfo, 
                        SAMLResponse resp) 
        throws TrustException {
                
-               if (resp.isSigned()&& !appinfo.validate(resp,role)) {
+        // If the entire Response is signed, check it
+               if (resp.isSigned()&& 
+            !appinfo.validate(resp,role)) {
                        throw new TrustException("Unable to validate signature of response");
                }
                
+        // Now check each Assertion in the Response for a signature
                Iterator assertions = resp.getAssertions();
                while (assertions.hasNext()) {
                        SAMLAssertion assertion = (SAMLAssertion) assertions.next();