More work on profile handlers, still have some more refactoring to do
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / idp / profile / saml2 / AbstractAttributeQuery.java
index f9b4c8a..4c45a33 100644 (file)
 
 package edu.internet2.middleware.shibboleth.idp.profile.saml2;
 
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
 import org.apache.log4j.Logger;
-import org.opensaml.common.SAMLObjectBuilder;
-import org.opensaml.saml2.core.Advice;
+import org.joda.time.DateTime;
+import org.opensaml.common.binding.BindingException;
+import org.opensaml.common.binding.decoding.MessageDecoder;
+import org.opensaml.common.binding.encoding.MessageEncoder;
+import org.opensaml.log.Level;
 import org.opensaml.saml2.core.Assertion;
-import org.opensaml.saml2.core.Audience;
-import org.opensaml.saml2.core.AudienceRestriction;
-import org.opensaml.saml2.core.Conditions;
-import org.opensaml.saml2.core.Issuer;
-import org.opensaml.saml2.core.ProxyRestriction;
+import org.opensaml.saml2.core.AttributeQuery;
+import org.opensaml.saml2.core.AttributeStatement;
 import org.opensaml.saml2.core.Response;
-import org.opensaml.saml2.core.Status;
-import org.opensaml.saml2.core.StatusCode;
-import org.opensaml.saml2.core.Subject;
-import org.opensaml.saml2.encryption.Encrypter;
-import org.opensaml.saml2.metadata.provider.MetadataProvider;
-import org.opensaml.xml.XMLObjectBuilder;
-import org.opensaml.xml.encryption.EncryptionException;
-import org.opensaml.xml.signature.Signature;
-import org.opensaml.xml.signature.Signer;
+import org.opensaml.saml2.metadata.provider.MetadataProviderException;
 
+import edu.internet2.middleware.shibboleth.common.attribute.AttributeRequestException;
 import edu.internet2.middleware.shibboleth.common.attribute.SAML2AttributeAuthority;
 import edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethAttributeRequestContext;
-import edu.internet2.middleware.shibboleth.common.attribute.provider.ShibbolethSAML2AttributeAuthority;
-import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolver;
+import edu.internet2.middleware.shibboleth.common.log.AuditLogEntry;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileException;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileRequest;
+import edu.internet2.middleware.shibboleth.common.profile.ProfileResponse;
 import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
 import edu.internet2.middleware.shibboleth.common.relyingparty.saml2.AttributeQueryConfiguration;
+import edu.internet2.middleware.shibboleth.idp.session.ServiceInformation;
+import edu.internet2.middleware.shibboleth.idp.session.Session;
 
 /**
  * SAML 2.0 Attribute Query profile handler.
@@ -51,308 +51,357 @@ public abstract class AbstractAttributeQuery extends AbstractSAML2ProfileHandler
     /** Class logger. */
     private static Logger log = Logger.getLogger(AbstractAttributeQuery.class);
 
-    /** For building response. */
-    private SAMLObjectBuilder<Response> responseBuilder;
-
-    /** For building status. */
-    private SAMLObjectBuilder<Status> statusBuilder;
-
-    /** For building statuscode. */
-    private SAMLObjectBuilder<StatusCode> statusCodeBuilder;
-
-    /** For building assertion. */
-    private SAMLObjectBuilder<Assertion> assertionBuilder;
-
-    /** For building issuer. */
-    private SAMLObjectBuilder<Issuer> issuerBuilder;
+    /** {@inheritDoc} */
+    public String getProfileId() {
+        return "urn:oasis:names:tc:SAML:2.0:profiles:query";
+    }
 
-    /** For building subject. */
-    private SAMLObjectBuilder<Subject> subjectBuilder;
+    /** {@inheritDoc} */
+    public void processRequest(ProfileRequest<ServletRequest> request, ProfileResponse<ServletResponse> response)
+            throws ProfileException {
 
-    /** For building conditions. */
-    private SAMLObjectBuilder<Conditions> conditionsBuilder;
+        AttributeQueryRequestContext requestContext = new AttributeQueryRequestContext(request, response);
 
-    /** For building audience restriction. */
-    private SAMLObjectBuilder<AudienceRestriction> audienceRestrictionBuilder;
+        getMessageDecoder(requestContext);
+        
+        decodeRequest(requestContext);
 
-    /** For building audience. */
-    private SAMLObjectBuilder<Audience> audienceBuilder;
+        buildResponse(requestContext);
 
-    /** For building advice. */
-    private SAMLObjectBuilder<Advice> adviceBuilder;
+        getMessageEncoder(requestContext);
 
-    /** For building signature. */
-    private XMLObjectBuilder<Signature> signatureBuilder;
+        try {
+            requestContext.getMessageEncoder().encode();
+            writeAuditLogEntry(requestContext);
+        } catch (BindingException e) {
+            log.error("Unable to encode response the relying party: " + requestContext.getRelyingPartyId(), e);
+            throw new ProfileException("Unable to encode response the relying party: "
+                    + requestContext.getRelyingPartyId(), e);
+        }
+    }
 
-    /** Attribute authority. */
-    private SAML2AttributeAuthority attributeAuthority;
+    /**
+     * Gets a populated message decoder.
+     * 
+     * @param requestContext 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;
 
     /**
-     * This creates a new attribute query.
+     * Gets a populated message encoder.
+     * 
+     * @param requestContext current request context
      * 
-     * @param ar <code>AttributeResolver</code>
+     * @throws ProfileException thrown if there is no message encoder that may be used to encoder the outgoing response
      */
-    public AbstractAttributeQuery(AttributeResolver<ShibbolethAttributeRequestContext> ar) {
-        // instantiate attribute authority
-        attributeAuthority = new ShibbolethSAML2AttributeAuthority(ar);
-
-        // instantiate XML builders
-        responseBuilder = (SAMLObjectBuilder<Response>) getBuilderFactory().getBuilder(Response.DEFAULT_ELEMENT_NAME);
-        statusBuilder = (SAMLObjectBuilder<Status>) getBuilderFactory().getBuilder(Status.DEFAULT_ELEMENT_NAME);
-        statusCodeBuilder = (SAMLObjectBuilder<StatusCode>) getBuilderFactory().getBuilder(
-                StatusCode.DEFAULT_ELEMENT_NAME);
-        issuerBuilder = (SAMLObjectBuilder<Issuer>) getBuilderFactory().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
-        assertionBuilder = (SAMLObjectBuilder<Assertion>) getBuilderFactory()
-                .getBuilder(Assertion.DEFAULT_ELEMENT_NAME);
-        subjectBuilder = (SAMLObjectBuilder<Subject>) getBuilderFactory().getBuilder(Subject.DEFAULT_ELEMENT_NAME);
-        conditionsBuilder = (SAMLObjectBuilder<Conditions>) getBuilderFactory().getBuilder(
-                Conditions.DEFAULT_ELEMENT_NAME);
-        audienceRestrictionBuilder = (SAMLObjectBuilder<AudienceRestriction>) getBuilderFactory().getBuilder(
-                AudienceRestriction.DEFAULT_ELEMENT_NAME);
-        audienceBuilder = (SAMLObjectBuilder<Audience>) getBuilderFactory().getBuilder(Audience.DEFAULT_ELEMENT_NAME);
-        adviceBuilder = (SAMLObjectBuilder<Advice>) getBuilderFactory().getBuilder(Advice.DEFAULT_ELEMENT_NAME);
-        signatureBuilder = (XMLObjectBuilder<Signature>) getBuilderFactory().getBuilder(Signature.DEFAULT_ELEMENT_NAME);
-    }
+    protected abstract void getMessageEncoder(AttributeQueryRequestContext requestContext) throws ProfileException;
 
     /**
-     * This returns the <code>RelyingPartyConfiguration</code> for the supplied provider id.
+     * Decodes the message in the request and adds it to the request context.
      * 
-     * @param providerId <code>String</code>
-     * @return <code>RelyingPartyConfiguration</code>
+     * @param requestContext request context contianing the request to decode
+     * 
+     * @throws ProfileException throw if there is a problem decoding the request
      */
-    protected RelyingPartyConfiguration getRelyingPartyConfiguration(String providerId) {
-        return getRelyingPartyConfigurationManager().getRelyingPartyConfiguration(providerId);
+    protected void decodeRequest(AttributeQueryRequestContext requestContext)
+            throws ProfileException {
+
+        try {
+            requestContext.getMessageDecoder().decode();
+            if (log.isDebugEnabled()) {
+                log.debug("decoded http servlet request");
+            }
+            requestContext.setAttributeQuery((AttributeQuery) requestContext.getMessageDecoder().getSAMLMessage());
+        } catch (BindingException e) {
+            log.error("Error decoding attribute query message", e);
+            throw new ProfileException("Error decoding attribute query message");
+        }
     }
 
     /**
-     * This returns the <code>AttributeQueryConfiguration</code> for the supplied provider id.
+     * Builds a response to the attribute query within the request context.
      * 
-     * @param providerId <code>String</code>
-     * @return <code>AttributeQueryConfiguration</code>
+     * @param requestContext current request context
+     * 
+     * @throws ProfileException thrown if there is a problem creating the SAML response
      */
-    protected AttributeQueryConfiguration getAttributeQueryConfiguration(String providerId) {
-        return (AttributeQueryConfiguration) getRelyingPartyConfiguration(providerId).getProfileConfigurations().get(
-                AttributeQueryConfiguration.PROFILE_ID);
+    protected void buildResponse(AttributeQueryRequestContext requestContext) throws ProfileException {
+        DateTime issueInstant = new DateTime();
+
+        // create the attribute statement
+        AttributeStatement attributeStatement = buildAttributeStatement(requestContext);
+
+        // create the assertion and add the attribute statement
+        Assertion assertion = buildAssertion(issueInstant, requestContext.getRelyingPartyConfiguration(),
+                requestContext.getProfileConfiguration());
+        assertion.getAttributeStatements().add(attributeStatement);
+
+        // create the SAML response and add the assertion
+        Response samlResponse = getResponseBuilder().buildObject();
+        populateStatusResponse(samlResponse, issueInstant, requestContext.getAttributeQuery(), requestContext
+                .getRelyingPartyConfiguration());
+        // TODO handle subject
+        samlResponse.getAssertions().add(assertion);
+
+        // sign the assertion if it should be signed
+        signAssertion(assertion, requestContext.getRelyingPartyConfiguration(), requestContext
+                .getProfileConfiguration());
+
+        requestContext.setAttributeQueryResponse(samlResponse);
     }
 
     /**
-     * This returns the <code>MetadataProvider</code> for this attribute query.
+     * Executes a query for attributes and builds a SAML attribute statement from the results.
      * 
-     * @return <code>MetadataProvider</code>
+     * @param requestContext current request context
+     * 
+     * @return attribute statement resulting from the query
+     * 
+     * @throws ProfileException thrown if there is a problem making the query
      */
-    protected MetadataProvider getMetadataProvider() {
-        return getRelyingPartyConfigurationManager().getMetadataProvider();
+    protected AttributeStatement buildAttributeStatement(AttributeQueryRequestContext requestContext)
+            throws ProfileException {
+        ShibbolethAttributeRequestContext attributeRequestContext = buildAttributeRequestContext(requestContext
+                .getRelyingPartyId(), requestContext.getUserSession(), requestContext.getProfileRequest());
+
+        try {
+            SAML2AttributeAuthority attributeAuthority = requestContext.getProfileConfiguration()
+                    .getAttributeAuthority();
+            return attributeAuthority.performAttributeQuery(attributeRequestContext);
+        } catch (AttributeRequestException e) {
+            log.error("Error resolving attributes", e);
+            throw new ProfileException("Error resolving attributes", e);
+        }
     }
 
     /**
-     * This returns the <code>AttributeAuthority</code> for this attribute query.
+     * Builds an attribute request context for this request.
      * 
-     * @return <code>SAML2AttributeAuthority</code>
+     * @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 SAML2AttributeAuthority getAttributeAuthority() {
-        return attributeAuthority;
+    protected ShibbolethAttributeRequestContext buildAttributeRequestContext(String spEntityId, Session userSession,
+            ProfileRequest<ServletRequest> request) throws ProfileException {
+        ServiceInformation spInformation = userSession.getServiceInformation(spEntityId);
+        ShibbolethAttributeRequestContext requestContext = null;
+        try {
+            requestContext = new ShibbolethAttributeRequestContext(getMetadataProvider(),
+                    getRelyingPartyConfiguration(spEntityId));
+            requestContext.setPrincipalName(userSession.getPrincipalID());
+            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);
+        }
     }
 
     /**
-     * This builds the response for this SAML request.
+     * Writes an aduit log entry indicating the successful response to the attribute request.
      * 
-     * @param responseContext <code>ProfileResponseContext</code>
-     * @return <code>Response</code>
-     * @throws EncryptionException if an error occurs attempting to encrypt data
+     * @param requestContext current request context
      */
-    protected Response buildResponse(ProfileResponseContext responseContext) throws EncryptionException {
-        AttributeQueryConfiguration config = getAttributeQueryConfiguration(responseContext.getProviderId());
+    protected void writeAuditLogEntry(AttributeQueryRequestContext requestContext) {
+        AuditLogEntry auditLogEntry = new AuditLogEntry();
+        auditLogEntry.setMessageProfile(getProfileId());
+        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());
+        getAduitLog().log(Level.CRITICAL, auditLogEntry);
+    }
+
+    /** Basic data structure used to accumulate information as a request is being processed. */
+    protected class AttributeQueryRequestContext {
+
+        /** Current user's session. */
+        private Session userSession;
+
+        /** Current profile request. */
+        private ProfileRequest<ServletRequest> profileRequest;
+
+        /** Decoder used to decode the incoming request. */
+        private MessageDecoder<ServletRequest> messageDecoder;
+
+        /** Current profile response. */
+        private ProfileResponse<ServletResponse> profileResponse;
+
+        /** 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;
 
-        /*
-         * required: samlp:Status, ID, Version, IssueInstant
+        /** 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
          */
-        Response response = responseBuilder.buildObject();
-        response.setVersion(SAML_VERSION);
-        response.setID(getIdGenerator().generateIdentifier());
-        response.setInResponseTo(responseContext.getIssuer());
-        response.setIssueInstant(responseContext.getIssueInstant());
-        response.setDestination(responseContext.getDestination());
+        public AttributeQueryRequestContext(ProfileRequest<ServletRequest> request,
+                ProfileResponse<ServletResponse> response) {
+            userSession = getSessionManager().getSession(getUserSessionId(request));
+            profileRequest = request;
+            profileResponse = response;
 
-        response.setIssuer(buildIssuer(responseContext));
+        }
 
-        /*
-         * Will be hard coded in the future: if (consent != null) { response.setConsent(consent); }
+        /**
+         * Gets the attribute query from the relying party.
          * 
+         * @return attribute query from the relying party
          */
+        public AttributeQuery getAttributeQuery() {
+            return attributeQuery;
+        }
 
-        /*
-         * No extensions currently exist, will be hardcorded in the future: if (extensions != null) {
-         * response.setExtensions(extensions); }
+        /**
+         * Sets the attribute query from the relying party. This also populates the relying party ID, configuration, and
+         * profile configuration using information from the query.
          * 
+         * @param query attribute query from the relying party
          */
+        public void setAttributeQuery(AttributeQuery query) {
+            attributeQuery = query;
+            relyingPartyId = attributeQuery.getIssuer().getValue();
+            relyingPartyConfiguration = getRelyingPartyConfigurationManager().getRelyingPartyConfiguration(
+                    relyingPartyId);
+            profileConfiguration = (AttributeQueryConfiguration) relyingPartyConfiguration
+                    .getProfileConfiguration(AttributeQueryConfiguration.PROFILE_ID);
+        }
 
-        if (config.getSignAssertions()) {
-            Signature s = buildSignature();
-            s.setSigningKey(config.getSigningCredential().getPrivateKey());
-            if (config.getEncryptAssertion()) {
-                // TODO load encryption parameters
-                Encrypter encrypter = null;
-                Assertion a = buildAssertion(responseContext);
-                a.setSignature(s);
-                Signer.signObject(s);
-                response.getEncryptedAssertions().add(encrypter.encrypt(a));
-            } else {
-                Assertion a = buildAssertion(responseContext);
-                a.setSignature(s);
-                Signer.signObject(s);
-                response.getAssertions().add(a);
-            }
-        } else {
-            if (config.getEncryptAssertion()) {
-                // TODO load encryption parameters
-                Encrypter encrypter = null;
-                response.getEncryptedAssertions().add(encrypter.encrypt(buildAssertion(responseContext)));
-            } else {
-                response.getAssertions().add(buildAssertion(responseContext));
-            }
+        /**
+         * Gets the attribute query response.
+         * 
+         * @return attribute query response
+         */
+        public Response getAttributeQueryResponse() {
+            return attributeQueryResponse;
         }
-        response.setStatus(buildStatus(StatusCode.SUCCESS_URI));
-        return response;
-    }
 
-    /**
-     * This builds the status response for this SAML request.
-     * 
-     * @param statusCodeUri <code>String</code> to set
-     * @return <code>Status</code>
-     */
-    private Status buildStatus(String statusCodeUri) {
-        Status status = statusBuilder.buildObject();
-        StatusCode statusCode = statusCodeBuilder.buildObject();
-        statusCode.setValue(statusCodeUri);
-        status.setStatusCode(statusCode);
-        return status;
-    }
+        /**
+         * Sets the attribute query response.
+         * 
+         * @param response attribute query response
+         */
+        public void setAttributeQueryResponse(Response response) {
+            attributeQueryResponse = response;
+        }
 
-    /**
-     * This builds the assertion for this SAML request.
-     * 
-     * @param responseContext <code>ProfileResponseContext</code>
-     * @return <code>Assertion</code>
-     * @throws EncryptionException if an error occurs attempting to encrypt data
-     */
-    private Assertion buildAssertion(ProfileResponseContext responseContext) throws EncryptionException {
-        AttributeQueryConfiguration config = getAttributeQueryConfiguration(responseContext.getProviderId());
+        /**
+         * Gets the decoder used to decode the request.
+         * 
+         * @return decoder used to decode the request
+         */
+        public MessageDecoder<ServletRequest> getMessageDecoder() {
+            return messageDecoder;
+        }
 
-        /*
-         * required: saml:Issuer, ID, Version, IssueInstant
+        /**
+         * Sets the decoder used to decode the request.
+         * 
+         * @param decoder decoder used to decode the request
          */
-        Assertion assertion = assertionBuilder.buildObject();
-        assertion.setID(getIdGenerator().generateIdentifier());
-        assertion.setIssueInstant(responseContext.getIssueInstant());
-        assertion.setVersion(SAML_VERSION);
-        assertion.setIssuer(buildIssuer(responseContext));
-
-        // build subject
-        assertion.setSubject(buildSubject(responseContext, config.getEncryptNameID()));
-        // build conditions
-        assertion.setConditions(buildConditions(responseContext));
-        // build advice
-        assertion.setAdvice(buildAdvice());
-        // add attribute statement
-        assertion.getAttributeStatements().add(responseContext.getAttributeStatement());
-        return assertion;
-    }
+        public void setMessageDecoder(MessageDecoder<ServletRequest> decoder) {
+            messageDecoder = decoder;
+        }
 
-    /**
-     * This builds the issuer response for this SAML request.
-     * 
-     * @param responseContext <code>ProfileResponseContext</code>
-     * @return <code>Issuer</code>
-     */
-    private Issuer buildIssuer(ProfileResponseContext responseContext) {
-        RelyingPartyConfiguration relyingPartyConfiguration = getRelyingPartyConfiguration(responseContext
-                .getProviderId());
-        Issuer issuer = issuerBuilder.buildObject();
-        issuer.setValue(relyingPartyConfiguration.getProviderId());
-        return issuer;
-    }
+        /**
+         * Gets the encoder used to encoder the response.
+         * 
+         * @return encoder used to encoder the response
+         */
+        public MessageEncoder<ServletResponse> getMessageEncoder() {
+            return messageEncoder;
+        }
 
-    /**
-     * This builds the subject for this SAML request.
-     * 
-     * @param responseContext <code>ProfileResponseContext</code>
-     * @param encryptNameId <code>boolean</code>
-     * @return <code>Subject</code>
-     * @throws EncryptionException if encryption of the name id fails
-     */
-    private Subject buildSubject(ProfileResponseContext responseContext, boolean encryptNameId)
-            throws EncryptionException {
-        Subject subject = subjectBuilder.buildObject();
-        if (encryptNameId) {
-            // TODO load encryption parameters
-            Encrypter encrypter = null;
-            subject.setEncryptedID(encrypter.encrypt(responseContext.getMessage().getSubject().getNameID()));
-        } else {
-            subject.setNameID(responseContext.getMessage().getSubject().getNameID());
-            // TODO when is subject.setBaseID(newBaseID) called, if ever?
+        /**
+         * Sets the encoder used to encoder the response.
+         * 
+         * @param encoder encoder used to encoder the response
+         */
+        public void setMessageEncoder(MessageEncoder<ServletResponse> encoder) {
+            messageEncoder = encoder;
         }
-        return subject;
-    }
 
-    /**
-     * This builds the conditions for this SAML request.
-     * 
-     * @param responseContext <code>ProfileResponseContext</code>
-     * @return <code>Conditions</code>
-     */
-    private Conditions buildConditions(ProfileResponseContext responseContext) {
-        AttributeQueryConfiguration config = getAttributeQueryConfiguration(responseContext.getProviderId());
-
-        Conditions conditions = conditionsBuilder.buildObject();
-        conditions.setNotBefore(responseContext.getIssueInstant());
-        conditions.setNotOnOrAfter(responseContext.getIssueInstant().plus(config.getAssertionLifetime()));
-
-        // add audience restrictions
-        AudienceRestriction audienceRestriction = audienceRestrictionBuilder.buildObject();
-        for (String s : config.getAssertionAudiences()) {
-            Audience audience = audienceBuilder.buildObject();
-            audience.setAudienceURI(s);
-            audienceRestriction.getAudiences().add(audience);
+        /**
+         * Gets the attribute profile configuration for the relying party.
+         * 
+         * @return attribute profile configuration for the relying party
+         */
+        public AttributeQueryConfiguration getProfileConfiguration() {
+            return profileConfiguration;
         }
-        conditions.getAudienceRestrictions().add(audienceRestriction);
-
-        // add proxy restrictions
-        ProxyRestriction proxyRestriction = conditions.getProxyRestriction();
-        for (String s : config.getProxyAudiences()) {
-            Audience audience = audienceBuilder.buildObject();
-            audience.setAudienceURI(s);
-            proxyRestriction.getAudiences().add(audience);
+
+        /**
+         * Gets the current profile request.
+         * 
+         * @return current profile request
+         */
+        public ProfileRequest<ServletRequest> getProfileRequest() {
+            return profileRequest;
         }
-        proxyRestriction.setProxyCount(new Integer(config.getProxyCount()));
 
-        /*
-         * OneTimeUse and additional conditions not supported yet
+        /**
+         * Gets the current profile response.
+         * 
+         * @return current profile response
          */
+        public ProfileResponse<ServletResponse> getProfileResponse() {
+            return profileResponse;
+        }
 
-        return conditions;
-    }
+        /**
+         * 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;
+        }
 
-    /**
-     * This builds the advice for this SAML request.
-     * 
-     * @return <code>Advice</code>
-     */
-    private Advice buildAdvice() {
-        /*
-         * Advice not supported at this time
+        /**
+         * Gets the ID of the relying party.
+         * 
+         * @return ID of the relying party
          */
-        Advice advice = adviceBuilder.buildObject();
-        return advice;
-    }
+        public String getRelyingPartyId() {
+            return relyingPartyId;
+        }
 
-    /**
-     * This builds a signature for this SAML request.
-     * 
-     * @return <code>Signature</code>
-     */
-    private Signature buildSignature() {
-        Signature signature = signatureBuilder.buildObject(Signature.DEFAULT_ELEMENT_NAME);
-        return signature;
+        /**
+         * Gets the current user's session.
+         * 
+         * @return current user's session
+         */
+        public Session getUserSession() {
+            return userSession;
+        }
     }
 }
\ No newline at end of file