More SAML attribute query unit test work (and related bug fixes) - Basic query flows...
authorlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 31 May 2007 16:05:45 +0000 (16:05 +0000)
committerlajoie <lajoie@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Thu, 31 May 2007 16:05:45 +0000 (16:05 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@2222 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

src/edu/internet2/middleware/shibboleth/idp/profile/saml2/AbstractAttributeQuery.java
src/edu/internet2/middleware/shibboleth/idp/profile/saml2/HTTPSOAPAttributeQuery.java
tests/data/conf1/attribute-resolver.xml
tests/data/conf1/internal.xml
tests/data/conf1/relying-party.xml
tests/edu/internet2/middleware/shibboleth/idp/system/conf1/SAML2AttributeQueryTestCase.java

index 20ad003..dd2690f 100644 (file)
@@ -28,10 +28,10 @@ import org.opensaml.log.Level;
 import org.opensaml.saml2.core.Assertion;
 import org.opensaml.saml2.core.AttributeQuery;
 import org.opensaml.saml2.core.AttributeStatement;
+import org.opensaml.saml2.core.RequestAbstractType;
 import org.opensaml.saml2.core.Response;
 import org.opensaml.saml2.core.Status;
 import org.opensaml.saml2.core.StatusCode;
-import org.opensaml.saml2.metadata.provider.MetadataProviderException;
 import org.opensaml.ws.security.SecurityPolicyException;
 
 import edu.internet2.middleware.shibboleth.common.attribute.AttributeRequestException;
@@ -63,131 +63,166 @@ public abstract class AbstractAttributeQuery extends AbstractSAML2ProfileHandler
     public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
             throws ProfileException {
 
-        AttributeQueryRequestContext requestContext = new AttributeQueryRequestContext(request, response);
+        AttributeQueryContext queryContext = new AttributeQueryContext(request, response);
 
-        getMessageDecoder(requestContext);
+        getMessageDecoder(queryContext);
 
         try {
-            decodeRequest(requestContext);
-            buildResponse(requestContext);
+            decodeRequest(queryContext);
+            buildAttributeRequestContext(queryContext);
+            buildResponse(queryContext);
         } catch (SecurityPolicyException e) {
-            buildErrorResponse(requestContext, e);
-        }catch (AttributeRequestException e){
-            buildErrorResponse(requestContext, e);
+            buildErrorResponse(queryContext, e);
+        } catch (AttributeRequestException e) {
+            buildErrorResponse(queryContext, e);
         }
 
-        getMessageEncoder(requestContext);
+        getMessageEncoder(queryContext);
 
         try {
-            requestContext.getMessageEncoder().encode();
-            writeAuditLogEntry(requestContext);
+            queryContext.getMessageEncoder().encode();
+            writeAuditLogEntry(queryContext);
         } catch (BindingException e) {
-            log.error("Unable to encode response the relying party: " + requestContext.getRelyingPartyId(), e);
+            log.error("Unable to encode response the relying party: "
+                    + queryContext.getAttributeRequestContext().getAttributeRequester(), e);
             throw new ProfileException("Unable to encode response the relying party: "
-                    + requestContext.getRelyingPartyId(), e);
+                    + queryContext.getAttributeRequestContext().getAttributeRequester(), e);
         }
     }
 
     /**
      * Gets a populated message decoder.
      * 
-     * @param requestContext current request context
+     * @param queryContext current request context
      * 
      * @throws ProfileException thrown if there is no message decoder that may be used to decoder the incoming request
      */
-    protected abstract void getMessageDecoder(AttributeQueryRequestContext requestContext) throws ProfileException;
+    protected abstract void getMessageDecoder(AttributeQueryContext queryContext) throws ProfileException;
 
     /**
      * Gets a populated message encoder.
      * 
-     * @param requestContext current request context
+     * @param queryContext current request context
      * 
      * @throws ProfileException thrown if there is no message encoder that may be used to encoder the outgoing response
      */
-    protected abstract void getMessageEncoder(AttributeQueryRequestContext requestContext) throws ProfileException;
+    protected abstract void getMessageEncoder(AttributeQueryContext queryContext) throws ProfileException;
 
     /**
      * Decodes the message in the request and adds it to the request context.
      * 
-     * @param requestContext request context contianing the request to decode
+     * @param queryContext request context contianing the request to decode
      * 
      * @throws ProfileException throw if there is a problem decoding the request
      * @throws SecurityPolicyException thrown if the message was decoded properly but did not meet the necessary
      *             security policy requirements
      */
-    protected void decodeRequest(AttributeQueryRequestContext requestContext) throws ProfileException,
-            SecurityPolicyException {
+    protected void decodeRequest(AttributeQueryContext queryContext) throws ProfileException, SecurityPolicyException {
 
         try {
-            requestContext.getMessageDecoder().decode();
+            queryContext.getMessageDecoder().decode();
             if (log.isDebugEnabled()) {
                 log.debug("decoded http servlet request");
             }
         } catch (BindingException e) {
             log.error("Error decoding attribute query message", e);
             throw new ProfileException("Error decoding attribute query message");
-        } finally{
-            requestContext.setAttributeQuery((AttributeQuery) requestContext.getMessageDecoder().getSAMLMessage());
         }
     }
 
     /**
+     * Creates an attribute request context for this attribute query and places it in the query context.
+     * 
+     * @param queryContext current query context
+     */
+    protected void buildAttributeRequestContext(AttributeQueryContext queryContext) {
+        AttributeQuery attributeQuery = (AttributeQuery) queryContext.getMessageDecoder().getSAMLMessage();
+        RelyingPartyConfiguration rpConfig = getRelyingPartyConfiguration(attributeQuery.getIssuer().getValue());
+
+        ShibbolethAttributeRequestContext requestContext = new ShibbolethAttributeRequestContext(getMetadataProvider(),
+                rpConfig, attributeQuery);
+        Session userSession = getSessionManager().getSession(getUserSessionId(queryContext.getProfileRequest()));
+        if (userSession != null) {
+            requestContext.setUserSession(userSession);
+            ServiceInformation serviceInfo = userSession.getServiceInformation(attributeQuery.getIssuer().getValue());
+            if (serviceInfo != null) {
+                requestContext.setPrincipalAuthenticationMethod(serviceInfo.getAuthenticationMethod()
+                        .getAuthenticationMethod());
+            }
+        }
+
+        requestContext.setEffectiveProfileConfiguration((AttributeQueryConfiguration) rpConfig
+                .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID));
+
+        requestContext.setRequest(queryContext.getProfileRequest().getRawRequest());
+        queryContext.setAttributeRequestContext(requestContext);
+    }
+
+    /**
      * Builds a response to the attribute query within the request context.
      * 
-     * @param requestContext current request context
+     * @param queryContext current request context
      * 
      * @throws ProfileException thrown if there is a problem creating the SAML response
      * @throws AttributeRequestException thrown if there is a problem resolving attributes
      */
-    protected void buildResponse(AttributeQueryRequestContext requestContext) throws ProfileException,
-            AttributeRequestException {
+    protected void buildResponse(AttributeQueryContext queryContext) throws ProfileException, AttributeRequestException {
+        AttributeQueryConfiguration profileConfiguration = (AttributeQueryConfiguration) queryContext
+                .getAttributeRequestContext().getEffectiveProfileConfiguration();
         DateTime issueInstant = new DateTime();
 
         // create the attribute statement
-        AttributeStatement attributeStatement = buildAttributeStatement(requestContext);
+        AttributeStatement attributeStatement = buildAttributeStatement(queryContext);
 
         // create the assertion and add the attribute statement
-        Assertion assertion = buildAssertion(issueInstant, requestContext.getRelyingPartyConfiguration(),
-                requestContext.getProfileConfiguration());
+        Assertion assertion = buildAssertion(issueInstant, queryContext.getAttributeRequestContext()
+                .getRelyingPartyConfiguration(), profileConfiguration);
         assertion.getAttributeStatements().add(attributeStatement);
 
         // create the SAML response and add the assertion
         Response samlResponse = getResponseBuilder().buildObject();
-        populateStatusResponse(samlResponse, issueInstant, requestContext.getAttributeQuery(), requestContext
+        populateStatusResponse(samlResponse, issueInstant, (RequestAbstractType) queryContext
+                .getAttributeRequestContext().getAttributeQuery(), queryContext.getAttributeRequestContext()
                 .getRelyingPartyConfiguration());
 
         // TODO handle subject
         samlResponse.getAssertions().add(assertion);
 
         // sign the assertion if it should be signed
-        signAssertion(assertion, requestContext.getRelyingPartyConfiguration(), requestContext
-                .getProfileConfiguration());
+        signAssertion(assertion, queryContext.getAttributeRequestContext().getRelyingPartyConfiguration(),
+                profileConfiguration);
 
         Status status = buildStatus(StatusCode.SUCCESS_URI, null, null);
         samlResponse.setStatus(status);
 
-        requestContext.setAttributeQueryResponse(samlResponse);
+        queryContext.setAttributeQueryResponse(samlResponse);
     }
 
     /**
      * Executes a query for attributes and builds a SAML attribute statement from the results.
      * 
-     * @param requestContext current request context
+     * @param queryContext current request context
      * 
      * @return attribute statement resulting from the query
      * 
      * @throws ProfileException thrown if there is a problem making the query
      * @throws AttributeRequestException thrown if there is a problem resolving attributes
      */
-    protected AttributeStatement buildAttributeStatement(AttributeQueryRequestContext requestContext)
-            throws ProfileException, AttributeRequestException {
-        ShibbolethAttributeRequestContext attributeRequestContext = buildAttributeRequestContext(requestContext
-                .getRelyingPartyId(), requestContext.getUserSession(), requestContext.getProfileRequest());
+    protected AttributeStatement buildAttributeStatement(AttributeQueryContext queryContext) throws ProfileException,
+            AttributeRequestException {
 
         try {
-            SAML2AttributeAuthority attributeAuthority = requestContext.getProfileConfiguration()
-                    .getAttributeAuthority();
-            return attributeAuthority.performAttributeQuery(attributeRequestContext);
+            AttributeQueryConfiguration profileConfiguration = (AttributeQueryConfiguration) queryContext
+                    .getAttributeRequestContext().getEffectiveProfileConfiguration();
+            if (profileConfiguration == null) {
+                log.error("No SAML 2 attribute query profile configuration is defined for relying party: "
+                        + queryContext.getAttributeRequestContext().getRelyingPartyConfiguration().getRelyingPartyId());
+                throw new AttributeRequestException(
+                        "SAML 2 attribute query is not configured for this relying party");
+            }
+
+            SAML2AttributeAuthority attributeAuthority = profileConfiguration.getAttributeAuthority();
+            return attributeAuthority.performAttributeQuery(queryContext.getAttributeRequestContext());
         } catch (AttributeRequestException e) {
             log.error("Error resolving attributes", e);
             throw e;
@@ -195,148 +230,97 @@ public abstract class AbstractAttributeQuery extends AbstractSAML2ProfileHandler
     }
 
     /**
-     * Builds an attribute request context for this request.
-     * 
-     * @param spEntityId entity ID of the service provider
-     * @param userSession current user's session
-     * @param request current request
-     * 
-     * @return the attribute request context
-     * 
-     * @throws ProfileException thrown if the metadata information can not be located for the given service provider
-     */
-    protected ShibbolethAttributeRequestContext buildAttributeRequestContext(String spEntityId, Session userSession,
-            ProfileRequest<ServletRequest> request) throws ProfileException {
-        ShibbolethAttributeRequestContext requestContext = null;
-        try {
-            requestContext = new ShibbolethAttributeRequestContext(getMetadataProvider(),
-                    getRelyingPartyConfiguration(spEntityId));
-            requestContext.setPrincipalName(userSession.getPrincipalID());
-            if (userSession != null) {
-                ServiceInformation spInformation = userSession.getServiceInformation(spEntityId);
-                requestContext.setPrincipalAuthenticationMethod(spInformation.getAuthenticationMethod()
-                        .getAuthenticationMethod());
-            }
-            requestContext.setRequest(request.getRawRequest());
-            return requestContext;
-        } catch (MetadataProviderException e) {
-            log.error("Error creating ShibbolethAttributeRequestContext", e);
-            throw new ProfileException("Error retrieving metadata", e);
-        }
-    }
-
-    /**
      * Constructs an SAML response message carrying a request error.
      * 
-     * @param requestContext current request context
+     * @param queryContext current request context
      * @param error the encountered error
      */
-    protected void buildErrorResponse(AttributeQueryRequestContext requestContext, Exception error) {
+    protected void buildErrorResponse(AttributeQueryContext queryContext, Exception error) {
+        AttributeQuery attributeQuery = (AttributeQuery) queryContext.getAttributeRequestContext().getAttributeQuery();
+        RelyingPartyConfiguration rpConfig = queryContext.getAttributeRequestContext().getRelyingPartyConfiguration();
+
         DateTime issueInstant = new DateTime();
         Response samlResponse = getResponseBuilder().buildObject();
-        populateStatusResponse(samlResponse, issueInstant, requestContext.getAttributeQuery(), requestContext
-                .getRelyingPartyConfiguration());
+        populateStatusResponse(samlResponse, issueInstant, attributeQuery, rpConfig);
 
-        Status status = buildStatus(StatusCode.RESPONDER_URI, StatusCode.REQUEST_DENIED_URI, error
+        Status status = buildStatus(StatusCode.REQUESTER_URI, StatusCode.REQUEST_DENIED_URI, error
                 .getLocalizedMessage());
+
         samlResponse.setStatus(status);
 
-        requestContext.setAttributeQueryResponse(samlResponse);
+        queryContext.setAttributeQueryResponse(samlResponse);
     }
 
     /**
      * Writes an aduit log entry indicating the successful response to the attribute request.
      * 
-     * @param requestContext current request context
+     * @param queryContext current request context
      */
-    protected void writeAuditLogEntry(AttributeQueryRequestContext requestContext) {
+    protected void writeAuditLogEntry(AttributeQueryContext queryContext) {
         AuditLogEntry auditLogEntry = new AuditLogEntry();
         auditLogEntry.setMessageProfile(getProfileId());
-        
-        if(requestContext.getUserSession() != null){
-            auditLogEntry.setPrincipalAuthenticationMethod(requestContext.getUserSession().getServiceInformation(
-                    requestContext.getRelyingPartyId()).getAuthenticationMethod().getAuthenticationMethod());
-            auditLogEntry.setPrincipalId(requestContext.getUserSession().getPrincipalID());
-        }
-
-        auditLogEntry.setProviderId(requestContext.getRelyingPartyConfiguration().getProviderId());
-        auditLogEntry.setRelyingPartyId(requestContext.getRelyingPartyId());
-        auditLogEntry.setRequestBinding(requestContext.getMessageDecoder().getBindingURI());
-        auditLogEntry.setRequestId(requestContext.getAttributeQuery().getID());
-        auditLogEntry.setResponseBinding(requestContext.getMessageEncoder().getBindingURI());
-        auditLogEntry.setResponseId(requestContext.getAttributeQueryResponse().getID());
+        auditLogEntry.setPrincipalAuthenticationMethod(queryContext.getAttributeRequestContext()
+                .getPrincipalAuthenticationMethod());
+        auditLogEntry.setPrincipalId(queryContext.getAttributeRequestContext().getPrincipalName());
+        auditLogEntry.setProviderId(queryContext.getAttributeRequestContext().getRelyingPartyConfiguration()
+                .getProviderId());
+        auditLogEntry.setRelyingPartyId(queryContext.getAttributeRequestContext().getAttributeRequester());
+        auditLogEntry.setRequestBinding(queryContext.getMessageDecoder().getBindingURI());
+        auditLogEntry.setRequestId(((AttributeQuery) queryContext.getAttributeRequestContext().getAttributeQuery())
+                .getID());
+        auditLogEntry.setResponseBinding(queryContext.getMessageEncoder().getBindingURI());
+        auditLogEntry.setResponseId(queryContext.getAttributeQueryResponse().getID());
         getAduitLog().log(Level.CRITICAL, auditLogEntry);
     }
 
     /** Basic data structure used to accumulate information as a request is being processed. */
-    protected class AttributeQueryRequestContext {
+    protected class AttributeQueryContext {
 
-        /** Current user's session. */
-        private Session userSession;
-
-        /** Current profile request. */
+        /** Curent profile request. */
         private ProfileRequest<ServletRequest> profileRequest;
 
+        /** Current profile response. */
+        private ProfileResponse<ServletResponse> profileResponse;
+
         /** Decoder used to decode the incoming request. */
         private MessageDecoder<ServletRequest> messageDecoder;
 
-        /** Current profile response. */
-        private ProfileResponse<ServletResponse> profileResponse;
+        /** Attribute request context for this attribute query. */
+        private ShibbolethAttributeRequestContext attributeRequestContext;
 
         /** Encoder used to encode the outgoing response. */
         private MessageEncoder<ServletResponse> messageEncoder;
 
-        /** Attribute query made by the relying party. */
-        private AttributeQuery attributeQuery;
-
         /** Attribute query response to the relying party. */
         private Response attributeQueryResponse;
 
-        /** ID of the relying party. */
-        private String relyingPartyId;
-
-        /** Relying party configuration information. */
-        private RelyingPartyConfiguration relyingPartyConfiguration;
-
-        /** Attribute query profile configuration for the relying party. */
-        private AttributeQueryConfiguration profileConfiguration;
-
         /**
          * Constructor.
          * 
          * @param request current profile request
          * @param response current profile response
          */
-        public AttributeQueryRequestContext(ProfileRequest<ServletRequest> request,
-                ProfileResponse<ServletResponse> response) {
-            userSession = getSessionManager().getSession(getUserSessionId(request));
+        public AttributeQueryContext(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response) {
             profileRequest = request;
             profileResponse = response;
-
         }
 
         /**
-         * Gets the attribute query from the relying party.
+         * Gets the attribute request context for this query.
          * 
-         * @return attribute query from the relying party
+         * @return attribute request context for this query
          */
-        public AttributeQuery getAttributeQuery() {
-            return attributeQuery;
+        public ShibbolethAttributeRequestContext getAttributeRequestContext() {
+            return attributeRequestContext;
         }
 
         /**
-         * Sets the attribute query from the relying party. This also populates the relying party ID, configuration, and
-         * profile configuration using information from the query.
+         * Sets the attribute request context for this query.
          * 
-         * @param query attribute query from the relying party
+         * @param context attribute request context for this query
          */
-        public void setAttributeQuery(AttributeQuery query) {
-            attributeQuery = query;
-            relyingPartyId = attributeQuery.getIssuer().getValue();
-            relyingPartyConfiguration = getRelyingPartyConfigurationManager().getRelyingPartyConfiguration(
-                    relyingPartyId);
-            profileConfiguration = (AttributeQueryConfiguration) relyingPartyConfiguration
-                    .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID);
+        public void setAttributeRequestContext(ShibbolethAttributeRequestContext context) {
+            attributeRequestContext = context;
         }
 
         /**
@@ -394,15 +378,6 @@ public abstract class AbstractAttributeQuery extends AbstractSAML2ProfileHandler
         }
 
         /**
-         * Gets the attribute profile configuration for the relying party.
-         * 
-         * @return attribute profile configuration for the relying party
-         */
-        public AttributeQueryConfiguration getProfileConfiguration() {
-            return profileConfiguration;
-        }
-
-        /**
          * Gets the current profile request.
          * 
          * @return current profile request
@@ -419,32 +394,5 @@ public abstract class AbstractAttributeQuery extends AbstractSAML2ProfileHandler
         public ProfileResponse<ServletResponse> getProfileResponse() {
             return profileResponse;
         }
-
-        /**
-         * Gets the configuration information specific to the relying party that made the attribute query.
-         * 
-         * @return configuration information specific to the relying party that made the attribute query
-         */
-        public RelyingPartyConfiguration getRelyingPartyConfiguration() {
-            return relyingPartyConfiguration;
-        }
-
-        /**
-         * Gets the ID of the relying party.
-         * 
-         * @return ID of the relying party
-         */
-        public String getRelyingPartyId() {
-            return relyingPartyId;
-        }
-
-        /**
-         * Gets the current user's session.
-         * 
-         * @return current user's session
-         */
-        public Session getUserSession() {
-            return userSession;
-        }
     }
 }
\ No newline at end of file
index 3c3e0cd..f3ed1cb 100644 (file)
@@ -39,7 +39,7 @@ public class HTTPSOAPAttributeQuery extends AbstractAttributeQuery {
 
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
-    protected void getMessageDecoder(AttributeQueryRequestContext requestContext) throws ProfileException {
+    protected void getMessageDecoder(AttributeQueryContext requestContext) throws ProfileException {
         MessageDecoder<ServletRequest> decoder = getMessageDecoderFactory().getMessageDecoder(BINDING);
         if (decoder == null) {
             throw new ProfileException("No request decoder was registered for binding type: " + BINDING);
@@ -52,7 +52,7 @@ public class HTTPSOAPAttributeQuery extends AbstractAttributeQuery {
 
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
-    protected void getMessageEncoder(AttributeQueryRequestContext requestContext) throws ProfileException {
+    protected void getMessageEncoder(AttributeQueryContext requestContext) throws ProfileException {
 
         MessageEncoder<ServletResponse> encoder = getMessageEncoderFactory().getMessageEncoder(BINDING);
         if (encoder == null) {
index 13ace52..20ebc26 100644 (file)
@@ -3,19 +3,33 @@
 <AttributeResolver xmlns="urn:mace:shibboleth:2.0:resolver"
                    xmlns:resolver="urn:mace:shibboleth:2.0:resolver"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                   xmlns:pc="urn:mace:shibboleth:2.0:resolver:pc:direct"
                    xmlns:simple="urn:mace:shibboleth:2.0:resolver:ad:simple"
                       xmlns:static="urn:mace:shibboleth:2.0:resolver:dc:static"
                       xsi:schemaLocation="urn:mace:shibboleth:2.0:resolver classpath:/schema/shibboleth-2.0-attribute-resolver.xsd
+                                       urn:mace:shibboleth:2.0:resolver:pc:direct classpath:/schema/shibboleth-2.0-attribute-resolver-pc-direct.xsd
                                        urn:mace:shibboleth:2.0:resolver:ad:simple classpath:/schema/shibboleth-2.0-attribute-resolver-ad-simple.xsd
                                        urn:mace:shibboleth:2.0:resolver:dc:static classpath:/schema/shibboleth-2.0-attribute-resolver-dc-static.xsd">
                                        
+    <resolver:AttributeDefinition xsi:type="simple:Simple" id="uid">
+        <resolver:DataConnectorDependency ref="static" />
+    </resolver:AttributeDefinition>
+    
+    <resolver:AttributeDefinition xsi:type="simple:Simple" id="cn">
+        <resolver:DataConnectorDependency ref="static" />
+    </resolver:AttributeDefinition>
+                                       
     <resolver:DataConnector xsi:type="static:Static" id="static">
         <static:Attribute id="uid">
-            <static:Value>testuser</static:Value>
+            <static:Value>testUser</static:Value>
         </static:Attribute>
         <static:Attribute id="cn">
             <static:Value>Test User</static:Value>
         </static:Attribute>
     </resolver:DataConnector>
     
+    <resolver:PrincipalConnector xsi:type="pc:Direct" 
+                                 id="directPC"
+                                 nameIDFormat="urn:oasis:names:tc:SAML:1.0:nameid-format:unspecified" />
+
 </AttributeResolver>
\ No newline at end of file
index b7a6537..777f129 100644 (file)
     
     <bean id="shibboleth.SessionManager" class="edu.internet2.middleware.shibboleth.idp.session.impl.SessionManagerImpl" />
     
+    <bean id="shibboleth.SAML2AttributeAuthority"
+          class="edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAML2AttributeAuthority">
+          <constructor-arg ref="shibboleth.AttributeResolver" />
+          <property name="filteringEngine" ref="shibboleth.AttributeFilterEngine" />
+    </bean>
+    
     <!-- We're not operating in a servlet container so this won't work -->
     <!-- 
     <bean id="shibboleth.ServletAttributeExporter"
index 3720bf0..6ad4227 100644 (file)
     
     <DefaultRelyingParty provider="http://example.org/IdP" />
     
-    <RelyingParty id="urn:mace:incommon"
+    <RelyingParty id="urn:example.org:unitTestFed"
                   provider="http://example.org/IdP">
-          <!-- 
-        <ProfileConfiguration xsi:type="saml:ShibbolethSSOProfile" />
-        <ProfileConfiguration xsi:type="saml:SAML2SSOProfile" />
-        -->
+        <ProfileConfiguration xsi:type="saml:SAML2AttributesQueryProfile" />
     </RelyingParty>
     
     <MetadataProvider id="UnitTestConf1" xsi:type="InlineMetadataProvider" xmlns="urn:mace:shibboleth:2.0:metadata">
-        <EntitiesDescriptor Name="urn:example.org:unitTestFed" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
-            <EntityDescriptor entityID="urn:example.org:unitTestFed:mysp">
+        <EntitiesDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
+            <EntityDescriptor entityID="urn:example.org:unitTest:sp1">
                 <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
                     <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://example.org/mySP" index="0" />
                     <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://example.org/mySP" index="0" />
                 </SPSSODescriptor>
             </EntityDescriptor>
+            <EntitiesDescriptor Name="urn:example.org:unitTestFed" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
+                <EntityDescriptor entityID="urn:example.org:unitTestFed:sp2">
+                    <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+                        <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://example.org/mySP" index="0" />
+                        <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://example.org/mySP" index="0" />
+                    </SPSSODescriptor>
+                </EntityDescriptor>
+            </EntitiesDescriptor>
         </EntitiesDescriptor>
     </MetadataProvider>
 
index 0e01ffb..7e256c7 100644 (file)
@@ -48,8 +48,8 @@ import edu.internet2.middleware.shibboleth.idp.profile.ShibbolethProfileResponse
 public class SAML2AttributeQueryTestCase extends BaseConf1TestCase {
 
     /** Tests a request where the Issuer can not be authenticated. */
-    public void testUnathenticatedIssuerAttributeQuery() throws Exception {
-        AttributeQuery query = buildAttributeQuery();
+    public void testUnathenticatedIssuer() throws Exception {
+        AttributeQuery query = buildAttributeQuery("urn:example.org:unitTest:sp1");
         String soapMessage = getSOAPMessage(query);
 
         MockHttpServletRequest servletRequest = new MockHttpServletRequest();
@@ -69,21 +69,74 @@ public class SAML2AttributeQueryTestCase extends BaseConf1TestCase {
         handler.processRequest(profileRequest, profileResponse);
 
         String response = servletResponse.getContentAsString();
-        assertTrue(response.contains("urn:oasis:names:tc:SAML:2.0:status:Responder"));
+        assertTrue(response.contains("urn:oasis:names:tc:SAML:2.0:status:Requester"));
         assertTrue(response.contains("urn:oasis:names:tc:SAML:2.0:status:RequestDenied"));
     }
+    
+    /** Test a request where the Issuer is authenticated and has not requested any specific attributes. */
+    public void testAuthenticatedIssuerNoProfileConfiguration() throws Exception {
+        AttributeQuery query = buildAttributeQuery("urn:example.org:unitTest:sp1");
+        String soapMessage = getSOAPMessage(query);
+
+        MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+        servletRequest.setPathInfo("/IdP/saml2/SOAP/AttributeQueryNoAuth");
+        servletRequest.setContent(soapMessage.getBytes());
+
+        MockHttpServletResponse servletResponse = new MockHttpServletResponse();
+
+        ShibbolethProfileHandlerManager handlerManager = (ShibbolethProfileHandlerManager) getApplicationContext()
+                .getBean("shibboleth.ProfileHandler");
+        ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
+        assertNotNull(handler);
+
+        // Process request
+        ProfileRequest profileRequest = new ShibbolethProfileRequest(servletRequest);
+        ProfileResponse profileResponse = new ShibbolethProfileResponse(servletResponse);
+        handler.processRequest(profileRequest, profileResponse);
+
+        String response = servletResponse.getContentAsString();
+        assertTrue(response.contains("urn:oasis:names:tc:SAML:2.0:status:Requester"));
+        assertTrue(response.contains("urn:oasis:names:tc:SAML:2.0:status:RequestDenied"));
+    }
+    
+    /** Test a request where the Issuer is authenticated and has not requested any specific attributes. */
+    public void testAuthenticatedIssuerNoRequestAttributes() throws Exception {
+        AttributeQuery query = buildAttributeQuery("urn:example.org:unitTestFed:sp2");
+        String soapMessage = getSOAPMessage(query);
+
+        MockHttpServletRequest servletRequest = new MockHttpServletRequest();
+        servletRequest.setPathInfo("/IdP/saml2/SOAP/AttributeQueryNoAuth");
+        servletRequest.setContent(soapMessage.getBytes());
 
+        MockHttpServletResponse servletResponse = new MockHttpServletResponse();
+
+        ShibbolethProfileHandlerManager handlerManager = (ShibbolethProfileHandlerManager) getApplicationContext()
+                .getBean("shibboleth.ProfileHandler");
+        ProfileHandler handler = handlerManager.getProfileHandler(servletRequest);
+        assertNotNull(handler);
+
+        // Process request
+        ProfileRequest profileRequest = new ShibbolethProfileRequest(servletRequest);
+        ProfileResponse profileResponse = new ShibbolethProfileResponse(servletResponse);
+        handler.processRequest(profileRequest, profileResponse);
+
+        String response = servletResponse.getContentAsString();
+        System.out.println(response);
+//        assertTrue(response.contains("urn:oasis:names:tc:SAML:2.0:status:Requester"));
+//        assertTrue(response.contains("urn:oasis:names:tc:SAML:2.0:status:RequestDenied"));
+    }
+    
     /**
      * Builds a basic attribute query.
      * 
      * @return basic attribute query
      */
     @SuppressWarnings("unchecked")
-    protected AttributeQuery buildAttributeQuery() {
+    protected AttributeQuery buildAttributeQuery(String requester) {
         SAMLObjectBuilder<Issuer> issuerBuilder = (SAMLObjectBuilder<Issuer>) builderFactory
                 .getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
         Issuer issuer = issuerBuilder.buildObject();
-        issuer.setValue("urn:example.org:unitTestFed:mysp");
+        issuer.setValue(requester);
 
         SAMLObjectBuilder<NameID> nameIdBuilder = (SAMLObjectBuilder<NameID>) builderFactory
                 .getBuilder(NameID.DEFAULT_ELEMENT_NAME);