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;
// 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 {
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) {
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();
}
/**
- * 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();