*/
package edu.internet2.middleware.shibboleth.serviceprovider;
+import java.security.Key;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.apache.log4j.Logger;
+import org.apache.xml.security.signature.XMLSignature;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLAttributeQuery;
import org.opensaml.SAMLAuthenticationStatement;
import org.opensaml.SAMLSubject;
import org.opensaml.XML;
+import edu.internet2.middleware.shibboleth.common.Credential;
+import edu.internet2.middleware.shibboleth.common.Credentials;
import edu.internet2.middleware.shibboleth.metadata.AttributeAuthorityDescriptor;
import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
import edu.internet2.middleware.shibboleth.serviceprovider.ServiceProviderConfig.ApplicationInfo;
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
return true;
}
+ /**
+ * Given a credentialId from the CredentialUse/RelyingParty stuff,
+ * find a corresponding Credential element and use its Key/Cert to
+ * sign the Request.
+ *
+ * @oaran credentials Credentials object from config file
+ * @param request SAML AA Query request
+ * @param credentialId Siging Id from CredentialUse
+ */
+ private static void possiblySignRequest(
+ Credentials credentials,
+ SAMLRequest request,
+ String credentialId) {
+
+
+ if (credentials==null) {
+ log.error("No Credentials Element in SP Config file.");
+ return;
+ }
+ Credential credential = credentials.getCredential(credentialId);
+ if (credential==null) {
+ log.error("No credential found for id "+credentialId);
+ return;
+ }
+ Key key = credential.getPrivateKey();
+ X509Certificate[] certificateChain = credential.getX509CertificateChain();
+ try {
+ request.sign(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,key,Arrays.asList(certificateChain));
+ log.debug("Attribute Request signed with "+credentialId);
+ } catch (SAMLException e) {
+ log.error("Unable to sign Attribute Request", e);
+ }
+ }
+
}
import x0.maceShibbolethTargetConfig1.ShibbolethTargetConfigDocument;
import x0.maceShibbolethTargetConfig1.ApplicationDocument.Application;
import x0.maceShibbolethTargetConfig1.ApplicationsDocument.Applications;
+import x0.maceShibbolethTargetConfig1.CredentialUseDocument.CredentialUse;
+import x0.maceShibbolethTargetConfig1.CredentialUseDocument.CredentialUse.RelyingParty;
import x0.maceShibbolethTargetConfig1.HostDocument.Host;
import x0.maceShibbolethTargetConfig1.HostDocument.Host.Scheme.Enum;
import x0.maceShibbolethTargetConfig1.PathDocument.Path;
return sessions.getTimeout();
}
+ /**
+ * Given the EntityDescriptor of an IdP, find the RelyingParty
+ * element of the CredentialsUse section that matches the
+ * Entity name or one of its parent group names and return
+ * the signing credential that should be used with it. If
+ * no specific match occurs, return the default siging
+ * credential.
+ *
+ * @param entity
+ * @return
+ */
+ String getCredentialIdForEntity(EntityDescriptor entity) {
+
+ // Get the ID URI of the Entity and all its parent groups
+ EntitiesDescriptor entitiesDescriptor = entity.getEntitiesDescriptor();
+ ArrayList idlist = new ArrayList();
+ idlist.add(entity.getId());
+ // An EntityDescriptor must have a name, while groups may have names
+ while (entitiesDescriptor!=null) {
+ String edname = entitiesDescriptor.getName();
+ if (edname!=null)
+ idlist.add(edname);
+ // Chain up to parent Element, until none left
+ entitiesDescriptor=entitiesDescriptor.getEntitiesDescriptor();
+ }
+
+ // Get the default signing Credential ID and the RelyingParty overrides
+ CredentialUse credentialUse = applicationConfig.getCredentialUse();
+ if (credentialUse==null) {
+ // An <Application> may not have one, so look to the enclosing <Applications>
+ credentialUse = defaultApplicationInfo.applicationConfig.getCredentialUse();
+ }
+ if (credentialUse == null)
+ return null; // If there is no CredentialsUse there is no signing
+ String defaultCredentialId = credentialUse.getSigning();
+ // If no signing= attribute (null), then don't sign
+ RelyingParty[] relyingPartyArray = credentialUse.getRelyingPartyArray();
+
+ // Search for a match of Entity/Group ID against an overriding RelyingParty
+ Iterator iterator = idlist.iterator();
+ while (iterator.hasNext()) {
+ String id = (String) iterator.next();
+ for (int i =0;i<relyingPartyArray.length;i++) {
+ if (relyingPartyArray[i].getName().equals(id)) {
+ // We have matched a RelyingParty override
+ String signingCredName = relyingPartyArray[i].getSigning();
+ // If no signing= attribute (null), then don't sign
+ return signingCredName;
+ }
+ }
+ }
+ // No RelyingParty match, so use the default
+ return defaultCredentialId;
+ }
+
/**
* Return the current array of objects that implement the
* ...metadata.Metadata interface