--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<IdPConfig
+ xmlns="urn:mace:shibboleth:idp:config:1.0"
+ xmlns:cred="urn:mace:shibboleth:credentials:1.0"
+ xmlns:name="urn:mace:shibboleth:namemapper:1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:mace:shibboleth:idp:config:1.0 ../schemas/shibboleth-idpconfig-1.0.xsd">
+
+ <RelyingParty
+ name="urn-x:test:1"
+ providerId="urn-x:test:id1"
+ signingCredential="test"
+ passThruErrors="true"
+ defaultNameID="foo"
+ extension1="foo"
+ extension2="bar"/>
+
+<!-- Add back later <AttributeResolver config="$IDP_HOME$/etc/resolver.xml"/>-->
+
+ <ReleasePolicyEngine>
+ <ArpRepository implementation="edu.internet2.middleware.shibboleth.aa.arp.provider.FileSystemArpRepository">
+ <Path>$IDP_HOME$/etc/arps/</Path>
+ </ArpRepository>
+ </ReleasePolicyEngine>
+
+ <Logging>
+ <ErrorLog level="WARN" location="$IDP_HOME$/logs/shib-error.log" />
+ <TransactionLog level="INFO" location="$IDP_HOME$/logs/shib-access.log" />
+ </Logging>
+
+ <Credentials xmlns="urn:mace:shibboleth:credentials:1.0">
+ <KeyStoreResolver Id="test" storeType="JKS">
+ <Path>/conf/keystore.jks</Path>
+ <KeyAlias>shibhs</KeyAlias>
+ <CertAlias>shibhs</CertAlias>
+ <StorePassword>shibhs</StorePassword>
+ <KeyPassword>shibhs</KeyPassword>
+ </KeyStoreResolver>
+ </Credentials>
+
+ <ProtocolHandler type="ShibbolethV1SSOHandler">
+ <Location>https?://[^:/]+(:(443|80))?/$IDP_WEBAPP_NAME$/SSO</Location>
+ </ProtocolHandler>
+
+ <MetadataProvider type="edu.internet2.middleware.shibboleth.metadata.FilesystemMetadataProvider"
+ path="$IDP_HOME$/etc/example-metadata.xml"/>
+
+</IdPConfig>
\ No newline at end of file
*/
public interface RelyingParty {
- // TODO add support for extension attributes via getAttribute(foo)
-
/**
* Returns the appropriate identity provider to create assertions for this relying party.
*
*/
public String getDefaultTarget();
+ /**
+ * Provides a mechanism for extension developers to pass relying party specific data into their extensions.
+ */
+ public String getCustomAttribute(String name);
+
}
package edu.internet2.middleware.shibboleth.common;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.opensaml.saml2.metadata.provider.MetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.xml.XMLObject;
+import org.w3c.dom.Attr;
import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import edu.internet2.middleware.shibboleth.idp.IdPConfig;
private boolean wantsAssertionsSigned = false;
private int preferredArtifactType = 1;
private String defaultTarget;
+ private Map<String, String> extensionAttributes = new HashMap<String, String>();
+ private Collection<String> knownAttributes = Arrays.asList(new String[]{"providerId", "passThruErrors",
+ "defaultToPOSTProfile", "singleAssertion", "signAssertions", "defaultTarget", "forceAttributePush",
+ "preferredArtifactType", "signingCredential"});
public RelyingPartyImpl(Element partyConfig, Credentials credentials) throws RelyingPartyMapperException {
// Initialize and Identity Provider object for this use by this relying party
identityProvider = new RelyingPartyIdentityProvider(providerId, signingCredential);
+ // Track extension attributes
+ NamedNodeMap nodeMap = ((Element) partyConfig).getAttributes();
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Attr attr = (Attr) nodeMap.item(i);
+ if (!knownAttributes.contains(attr.getName())) {
+ extensionAttributes.put(attr.getName(), attr.getValue());
+ }
+ }
}
public IdentityProvider getIdentityProvider() {
return defaultTarget;
}
+ public String getCustomAttribute(String name) {
+
+ return extensionAttributes.get(name);
+ }
+
/**
* Default identity provider implementation.
*
return credential;
}
}
+
}
class NamedRelyingParty extends RelyingPartyImpl {
fail("Unable to load XML parser: " + e.getMessage());
}
}
+
+ public void testCustomAttributes() {
+
+ try {
+ // Parse IdP config file
+ String fileLocation = "data/relyingPartyMapper3.xml";
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(false);
+ factory.setNamespaceAware(true);
+
+ // We have to get a credentials set in order to init the mapper
+ NodeList credentialNodes = factory.newDocumentBuilder().parse(
+ new InputSource(new FileInputStream(fileLocation))).getDocumentElement().getElementsByTagNameNS(
+ Credentials.credentialsNamespace, "Credentials");
+ Credentials credentials = new Credentials((Element) credentialNodes.item(0));
+
+ RelyingPartyMapper mapper = new RelyingPartyMapper(factory.newDocumentBuilder().parse(
+ new InputSource(new FileInputStream(fileLocation))).getDocumentElement(), credentials);
+
+ // Make sure we can lookup by providerId
+ assertNotNull("Expected relying party lookup to succeed.", mapper.getRelyingParty("urn-x:test:1"));
+
+ // Check the extended config data for the relying party
+ assertEquals("Incorrect extenstion attribute for relying party.", "foo", mapper.getRelyingParty(
+ "urn-x:test:1").getCustomAttribute("extension1"));
+ assertEquals("Incorrect extension attribute for relying party.", "bar", mapper.getRelyingParty(
+ "urn-x:test:1").getCustomAttribute("extension2"));
+ assertNull("Incorrect extension attribute for relying party.", mapper.getRelyingParty("urn-x:test:1")
+ .getCustomAttribute("extension3"));
+ assertNull("Incorrect extension attribute for relying party.", mapper.getRelyingParty("urn-x:test:1")
+ .getCustomAttribute("providerId"));
+
+ } catch (SAXException e) {
+ fail("Error in test specification: " + e.getMessage());
+ } catch (IOException e) {
+ fail("Error in test specification: " + e.getMessage());
+ } catch (RelyingPartyMapperException e) {
+ fail("Unable to load relying party mapper: " + e.getMessage());
+ } catch (ParserConfigurationException e) {
+ fail("Unable to load XML parser: " + e.getMessage());
+ }
+ }
}
\ No newline at end of file