/*
+ * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
* ServiceProviderConfig.java
*
* A ServiceProviderConfig object holds an instance of the Shibboleth
* configuration file should be noted while processing continues.
* This strategy reports all the errors in all the files to the log
* rather than stopping at the first error.
- *
- * --------------------
- * Copyright 2002, 2004
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- * [Thats all we have to say to protect ourselves]
- * Your permission to use this code is governed by "The Shibboleth License".
- * A copy may be found at http://shibboleth.internet2.edu/license.html
- * [Nothing in copyright law requires license text in every file.]
*/
package edu.internet2.middleware.shibboleth.serviceprovider;
-import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.TreeMap;
import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLAttribute;
import org.opensaml.SAMLAttributeStatement;
import org.opensaml.SAMLException;
-import org.opensaml.SAMLObject;
+import org.opensaml.SAMLSignedObject;
+import org.opensaml.artifact.Artifact;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
import x0.maceShibboleth1.AttributeAcceptancePolicyDocument;
import x0.maceShibbolethTargetConfig1.ApplicationDocument;
+import x0.maceShibbolethTargetConfig1.LocalConfigurationType;
import x0.maceShibbolethTargetConfig1.PluggableType;
import x0.maceShibbolethTargetConfig1.RequestMapDocument;
+import x0.maceShibbolethTargetConfig1.SPConfigDocument;
+import x0.maceShibbolethTargetConfig1.SPConfigType;
import x0.maceShibbolethTargetConfig1.ShibbolethTargetConfigDocument;
import x0.maceShibbolethTargetConfig1.ApplicationDocument.Application;
import x0.maceShibbolethTargetConfig1.ApplicationsDocument.Applications;
import x0.maceShibbolethTargetConfig1.HostDocument.Host;
+import x0.maceShibbolethTargetConfig1.HostDocument.Host.Scheme.Enum;
import x0.maceShibbolethTargetConfig1.PathDocument.Path;
-import x0.maceShibbolethTargetConfig1.SHIREDocument.SHIRE;
-import x0.maceShibbolethTargetConfig1.ShibbolethTargetConfigDocument.ShibbolethTargetConfig;
-import edu.internet2.middleware.shibboleth.common.AAP;
-import edu.internet2.middleware.shibboleth.common.AttributeRule;
+import edu.internet2.middleware.shibboleth.aap.AAP;
+import edu.internet2.middleware.shibboleth.aap.AttributeRule;
+import edu.internet2.middleware.shibboleth.aap.provider.XMLAAPProvider;
import edu.internet2.middleware.shibboleth.common.Credentials;
+import edu.internet2.middleware.shibboleth.common.PluggableConfigurationComponent;
import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
-import edu.internet2.middleware.shibboleth.common.XML;
+import edu.internet2.middleware.shibboleth.common.Trust;
+import edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrust;
+import edu.internet2.middleware.shibboleth.metadata.EntitiesDescriptor;
import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
-import edu.internet2.middleware.shibboleth.metadata.EntityLocator;
import edu.internet2.middleware.shibboleth.metadata.Metadata;
-import edu.internet2.middleware.shibboleth.metadata.Provider;
-import edu.internet2.middleware.shibboleth.metadata.ProviderRole;
+import edu.internet2.middleware.shibboleth.metadata.RoleDescriptor;
+import edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadataProvider;
import edu.internet2.middleware.shibboleth.xml.Parser;
/**
*/
public class ServiceProviderConfig {
-
+ // Map key prefix for inline plugin configuration elements
private static final String INLINEURN = "urn:inlineBS:ID";
- private static Logger log = Logger.getLogger(ServiceProviderConfig.class);
+
+ private static Logger initlog = Logger.getLogger(ContextListener.SHIBBOLETH_INIT+".Config");
+ private static Logger reqlog = Logger.getLogger(ServiceProviderConfig.class);
- private ShibbolethTargetConfig // The XMLBean from the main config file
- config = null; // (i.e. shibboleth.xml)
+ private SPConfigType // The XMLBean from the main config file
+ config = null;
/*
* for a given configured or default application.
*/
- // Note EntityLocator extends and renames the old "Metadata" interface
- private Map/*<String, EntityLocator>*/ entityLocators =
- new TreeMap/*<String, EntityLocator>*/();
+ private Map/*<String, Metadata>*/ entityLocators =
+ new TreeMap/*<String, Metadata>*/();
- public void addOrReplaceMetadataImplementor(String uri, EntityLocator m) {
+ public void addOrReplaceMetadataImplementor(String uri, Metadata m) {
+ initlog.info("addOrReplaceMetadataImplementor " + uri+ " as "+m.getClass());
entityLocators.put(uri, m);
}
- public EntityLocator getMetadataImplementor(String uri) {
- return (EntityLocator) entityLocators.get(uri);
+ public Metadata getMetadataImplementor(String uri) {
+ return (Metadata)entityLocators.get(uri);
}
private Map/*<String, AAP>*/ attributePolicies =
new TreeMap/*<String, AAP>*/();
public void addOrReplaceAAPImplementor(String uri, AAP a) {
+ initlog.info("addOrReplaceAAPImplementor " + uri+ " as "+a.getClass());
attributePolicies.put(uri,a);
}
return (AAP) attributePolicies.get(uri);
}
- private Map/*<String, ITrust>*/ certificateValidators =
- new TreeMap/*<String, ITrust>*/();
+ private Map/*<String, Trust>*/ certificateValidators =
+ new TreeMap/*<String, Trust>*/();
- public void addOrReplaceTrustImplementor(String uri, ITrust t) {
+ public void addOrReplaceTrustImplementor(String uri, Trust t) {
+ initlog.info("addOrReplaceTrustImplementor " + uri+ " as "+t.getClass());
certificateValidators.put(uri,t);
}
- public ITrust getTrustImplementor(String uri) {
- return (ITrust) certificateValidators.get(uri);
+ public Trust getTrustImplementor(String uri) {
+ return (Trust) certificateValidators.get(uri);
}
+ private Trust[] defaultTrust = {new ShibbolethTrust()};
/*
* Objects created from the <Application(s)> elements.
/*
* A few constants
*/
- private final String SCHEMADIR = "/schemas/";
- private final String MAINSCHEMA = SCHEMADIR + XML.MAIN_SHEMA_ID;
- private final String METADATASCHEMA = SCHEMADIR + XML.SHIB_SCHEMA_ID;
- private final String TRUSTSCHEMA = SCHEMADIR + XML.TRUST_SCHEMA_ID;
- private final String AAPSCHEMA = SCHEMADIR + XML.SHIB_SCHEMA_ID;
private static final String XMLTRUSTPROVIDERTYPE =
- "edu.internet2.middleware.shibboleth.common.provider.XMLTrust";
+ "edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrust";
private static final String XMLAAPPROVIDERTYPE =
- "edu.internet2.middleware.shibboleth.serviceprovider.XMLAAP";
+ "edu.internet2.middleware.shibboleth.aap.provider.XMLAAP";
private static final String XMLFEDERATIONPROVIDERTYPE =
- "edu.internet2.middleware.shibboleth.common.provider.XMLMetadata";
- private static final String XMLREVOCATIONPROVIDERTYPE =
- "edu.internet2.middleware.shibboleth.common.provider.XMLRevocation";
+ "edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadata";
private static final String XMLREQUESTMAPPROVIDERTYPE =
- "edu.internet2.middleware.shibboleth.serviceprovider.XMLRequestMap";
+ "edu.internet2.middleware.shibboleth.sp.provider.NativeRequestMapProvider";
private static final String XMLCREDENTIALSPROVIDERTYPE =
"edu.internet2.middleware.shibboleth.common.Credentials";
throws ShibbolethConfigurationException {
if (config!=null) {
- log.error("ServiceProviderConfig.loadConfigObjects may not be called twice for the same object.");
+ initlog.error("ServiceProviderConfig.loadConfigObjects may not be called twice for the same object.");
throw new ShibbolethConfigurationException("Cannot reload configuration into same object.");
}
+
+ initlog.info("Loading SP configuration from "+configFilePath);
Document configDoc;
try {
configDoc = Parser.loadDom(configFilePath, true);
} catch (Exception e) {
+ initlog.error("XML Parser error "+e.toString());
throw new ShibbolethConfigurationException("XML error in "+configFilePath);
}
loadConfigBean(configDoc);
String urlhostname = url.getHost();
String urlpath = url.getPath();
int urlport = url.getPort();
- if (urlport==0) {
- if (urlscheme.equals("http"))
- urlport=80;
- else if (urlscheme.equals("https"))
- urlport=443;
- }
// find Host entry for this virtual server
Host[] hostArray = requestMap.getHostArray();
for (int ihost=0;ihost<hostArray.length;ihost++) {
Host host = hostArray[ihost];
- String hostScheme = host.getScheme().toString();
+ Enum scheme = host.getScheme();
String hostName = host.getName();
String hostApplicationId = host.getApplicationId();
long hostport = host.getPort();
- if (hostport==0) {
- if (hostScheme.equals("http"))
- hostport=80;
- else if (hostScheme.equals("https"))
- hostport=443;
- }
- if (!urlscheme.equals(hostScheme) ||
- !urlhostname.equals(hostName)||
+ if (scheme != null &&
+ !urlscheme.equals(scheme.toString()))
+ continue;
+ if (!urlhostname.equals(hostName))
+ continue;
+ if (hostport!=0 &&
+ urlport!=0 &&
urlport!=hostport)
continue;
}
}
+ reqlog.debug("mapRequest mapped "+urlreq+" into "+applicationId);
return applicationId;
}
private void loadConfigBean(Document configDoc)
throws ShibbolethConfigurationException {
boolean anyError=false;
- ShibbolethTargetConfigDocument configBeanDoc;
- try {
- // reprocess the already validated DOM to create a bean with typed fields
- // dump the trash (comments, processing instructions, extra whitespace)
- configBeanDoc = ShibbolethTargetConfigDocument.Factory.parse(configDoc,
- new XmlOptions().setLoadStripComments().setLoadStripProcinsts().setLoadStripWhitespace());
- config=configBeanDoc.getShibbolethTargetConfig();
+
+ Element documentElement = configDoc.getDocumentElement();
+ // reprocess the already validated DOM to create a bean with typed fields
+ // dump the trash (comments, processing instructions, extra whitespace)
+ try {
+ if (documentElement.getLocalName().equals("ShibbolethTargetConfig")) {
+ initlog.debug("SP Configuration file is in 1.2 syntax.");
+ ShibbolethTargetConfigDocument configBeanDoc;
+ configBeanDoc = ShibbolethTargetConfigDocument.Factory.parse(configDoc,
+ new XmlOptions().setLoadStripComments().setLoadStripProcinsts().setLoadStripWhitespace());
+ config = configBeanDoc.getShibbolethTargetConfig();
+ } else if (documentElement.getLocalName().equals("SPConfig")) {
+ initlog.debug("SP Configuration file is in 1.3 syntax.");
+ SPConfigDocument configBeanDoc;
+ configBeanDoc = SPConfigDocument.Factory.parse(configDoc,
+ new XmlOptions().setLoadStripComments().setLoadStripProcinsts().setLoadStripWhitespace());
+ config = configBeanDoc.getSPConfig();
+ } else {
+ initlog.error("Root element not ShibbolethTargetConfig or SPConfig");
+ throw new XmlException("Root element not ShibbolethTargetConfig or SPConfig");
+ }
} catch (XmlException e) {
// Since the DOM was already validated against the schema, errors will not typically occur here
- log.error("Error while parsing shibboleth configuration");
+ initlog.error("Error while parsing shibboleth configuration");
throw new ShibbolethConfigurationException("Error while parsing shibboleth configuration");
}
- // Extract the "root Element" object from the "Document" object
- ShibbolethTargetConfig config = configBeanDoc.getShibbolethTargetConfig();
+ String loggerUrlString = config.getLogger();
+ if (loggerUrlString!=null) {
+ try {
+ URL loggerURL = new URL(loggerUrlString);
+ initlog.warn("logging is being reconfigured by "+ loggerUrlString);
+ PropertyConfigurator.configure(loggerURL);
+ } catch (MalformedURLException e) {
+ // This error is not serious enough to prevent initialization
+ initlog.error("Ignoring invalid value for logger attribute "+loggerUrlString );
+ }
+ }
Applications apps = config.getApplications(); // <Applications>
defaultApp.setCredentialUse(apps.getCredentialUse());
defaultApp.setErrors(apps.getErrors());
defaultApp.setFederationProviderArray(apps.getFederationProviderArray());
+ defaultApp.setMetadataProviderArray(apps.getMetadataProviderArray());
defaultApp.setProviderId(apps.getProviderId());
- defaultApp.setRevocationProviderArray(apps.getRevocationProviderArray());
defaultApp.setSessions(apps.getSessions());
- defaultApp.setSignedAssertions(apps.getSignedAssertions());
- defaultApp.setSignedResponse(apps.getSignedResponse());
- defaultApp.setSignRequest(apps.getSignRequest());
defaultApp.setTrustProviderArray(apps.getTrustProviderArray());
/*
anyError |= processCredentials();
anyError |= processPluggableRequestMapProvider();
- if (anyError)
+ if (anyError) {
+ initlog.error("SP Initialization terminated due to configuration errors");
throw new ShibbolethConfigurationException("Errors processing configuration file, see log");
+ }
}
* Routine to handle CredentialProvider
*
* <p>Note: This only handles in-line XML.
- * Also, Credentials was an existing Origin class, so it doesn't
+ * Also, Credentials was an existing IdP class, so it doesn't
* implement the new PluggableConfigurationComponent interface and
* can't be loaded by generic plugin support.
* </p>
String pluggabletype = pluggable[i].getType();
if (!pluggabletype.equals(
"edu.internet2.middleware.shibboleth.common.Credentials")) {
- log.error("Unsupported CredentialsProvider type "+pluggabletype);
+ initlog.error("Unsupported CredentialsProvider type "+pluggabletype);
anyError=true;
continue;
}
Node credentialsNode=credentialsProviderNode.getFirstChild();
credentials = new Credentials((Element)credentialsNode);
} catch(Exception e) {
- log.error("Cannot process Credentials element of Shibboleth configuration");
- log.error(e);
+ initlog.error("Cannot process Credentials element of Shibboleth configuration",e);
anyError=true;
continue;
}
* object is stored in the appropriate Map.</p>
*
* <p>The objects created implement two interfaces. Mostly they
- * implement a configuration interface (EntityDescriptor, ITrust,
+ * implement a configuration interface (EntityDescriptor, Trust,
* AAP, etc). However, for the purpose of this routine they also
* must be declared to implement PluggableConfigurationComponent
* and provide an initialize() method that parses a DOM Node
Class implclass,
Class interfaceClass,
String builtinName,
- String schemaname,
Map /*<String,PluggableConfigurationComponent>*/uriMap
) {
if (!pluggabletype.equals(builtinName)) {
// Not the builtin type, try to load user class by name
+ initlog.info("loading user-specified pluggable class "+pluggabletype);
try {
implclass = Class.forName(pluggabletype);
} catch (ClassNotFoundException e) {
- log.error("Type value "+pluggabletype+" not found as supplied Java class");
+ initlog.error("Type value "+pluggabletype+" not found as supplied Java class");
return null;
}
if (!interfaceClass.isAssignableFrom(implclass)||
!PluggableConfigurationComponent.class.isAssignableFrom(implclass)) {
- log.error(pluggabletype+" class does not support required interfaces.");
+ initlog.error(pluggabletype+" class does not support required interfaces.");
return null;
}
}
try {
impl = (PluggableConfigurationComponent) implclass.newInstance();
} catch (Exception e) {
- log.error("Unable to instantiate "+pluggabletype);
+ initlog.error("Unable to instantiate "+pluggabletype);
return null;
}
try {
Node fragment = pluggable.newDomNode(); // XML-Fragment node
Node pluggableNode = fragment.getFirstChild(); // PluggableType
- Node contentNode=pluggableNode.getFirstChild();// root element
+ Element contentNode=(Element) pluggableNode.getFirstChild();// root element
impl.initialize(contentNode);
} catch (Exception e) {
- log.error("XML error " + e);
+ initlog.error("XML error " + e);
return null;
}
return "";
}
- String tempname = impl.getSchemaPathname();
- if (tempname!=null)
- schemaname=tempname;
-
try {
Document extdoc = Parser.loadDom(uri,true);
if (extdoc==null)
return null;
- impl.initialize(extdoc);
+ impl.initialize(extdoc.getDocumentElement());
} catch (Exception e) {
- log.error("XML error " + e);
+ initlog.error("XML error " + e);
return null;
}
}
*/
private boolean processPluggableMetadata(ApplicationInfo appinfo) {
boolean anyError = false;
- PluggableType[] pluggable = appinfo.getApplicationConfig().getFederationProviderArray();
+ PluggableType[] pluggable1 = appinfo.getApplicationConfig().getFederationProviderArray();
+ PluggableType[] pluggable2 = appinfo.getApplicationConfig().getMetadataProviderArray();
+ PluggableType[] pluggable;
+ if (pluggable1.length==0) {
+ pluggable=pluggable2;
+ } else if (pluggable2.length==0) {
+ pluggable=pluggable1;
+ } else {
+ pluggable = new PluggableType[pluggable1.length+pluggable2.length];
+ for (int i=0;i<pluggable2.length;i++) {
+ pluggable[i]=pluggable2[i];
+ }
+ for (int i=0;i<pluggable1.length;i++) {
+ pluggable[i+pluggable2.length]=pluggable1[i];
+ }
+ }
for (int i = 0;i<pluggable.length;i++) {
String uri = processPluggable(pluggable[i],
- XMLMetadataImpl.class,
- EntityLocator.class,
+ XMLMetadataProvider.class,
+ Metadata.class,
XMLFEDERATIONPROVIDERTYPE,
- METADATASCHEMA,
entityLocators);
if (uri==null)
anyError=true;
Document sitedoc = Parser.loadDom(uri,true);
if (sitedoc==null)
return false;
- XMLMetadataImpl impl = new XMLMetadataImpl();
- impl.initialize(sitedoc);
+ XMLMetadataProvider impl = new XMLMetadataProvider();
+ impl.initialize(sitedoc.getDocumentElement());
addOrReplaceMetadataImplementor(uri,impl);
} catch (Exception e) {
- log.error("Error while parsing Metadata file "+uri);
- log.error("XML error " + e);
+ initlog.error("Error while parsing Metadata file "+uri);
+ initlog.error("XML error " + e);
return false;
}
return true;
PluggableType[] pluggable = appinfo.getApplicationConfig().getAAPProviderArray();
for (int i = 0;i<pluggable.length;i++) {
String uri = processPluggable(pluggable[i],
- XMLAAPImpl.class,
+ XMLAAPProvider.class,
AAP.class,
XMLAAPPROVIDERTYPE,
- AAPSCHEMA,
attributePolicies);
if (uri==null)
anyError=true;
if (aapdoc==null)
return false;
AttributeAcceptancePolicyDocument aap = AttributeAcceptancePolicyDocument.Factory.parse(aapdoc);
- XMLAAPImpl impl = new XMLAAPImpl();
- impl.initialize(aapdoc);
+ XMLAAPProvider impl = new XMLAAPProvider();
+ impl.initialize(aapdoc.getDocumentElement());
addOrReplaceAAPImplementor(uri,impl);
} catch (Exception e) {
- log.error("Error while parsing AAP file "+uri);
- log.error("XML error " + e);
+ initlog.error("Error while parsing AAP file "+uri);
+ initlog.error("XML error " + e);
return false;
}
return true;
PluggableType[] pluggable = appinfo.getApplicationConfig().getTrustProviderArray();
for (int i = 0;i<pluggable.length;i++) {
String uri = processPluggable(pluggable[i],
- XMLTrustImpl.class,
- ITrust.class,
+ ShibbolethTrust.class,
+ Trust.class,
XMLTRUSTPROVIDERTYPE,
- TRUSTSCHEMA,
certificateValidators);
if (uri==null)
anyError=true;
return anyError;
}
- /**
- * Reload XML Trust configuration after file changed.
- * @param uri Path to Trust XML configuration
- * @return true if file reloaded.
- */
- public boolean reloadTrust(String uri) {
- if (getTrustImplementor(uri)!=null||
- uri.startsWith(INLINEURN))
- return false;
- try {
- Document trustdoc = Parser.loadDom(uri,true);
- if (trustdoc==null)
- return false;
- XMLTrustImpl impl = new XMLTrustImpl();
- impl.initialize(trustdoc);
- addOrReplaceTrustImplementor(uri,impl);
- } catch (Exception e) {
- log.error("Error while parsing Trust file "+uri);
- log.error("XML error " + e);
- return false;
- }
- return true;
- }
private boolean processPluggableRequestMapProvider(){
- SHIRE shire = config.getSHIRE();
+ LocalConfigurationType shire = config.getSHIRE();
+ if (shire==null)
+ shire = config.getLocal();
+ if (shire==null) {
+ initlog.error("No SHIRE or Local element.");
+ return true;
+ }
PluggableType mapProvider = shire.getRequestMapProvider();
String pluggabletype = mapProvider.getType();
if (!pluggabletype.equals(XMLREQUESTMAPPROVIDERTYPE)) {
- log.error("Unsupported RequestMapProvider type "+pluggabletype);
+ initlog.error("Unsupported RequestMapProvider type "+pluggabletype);
return true;
}
requestMapDoc = RequestMapDocument.Factory.parse(contentNode);
} catch (Exception e) {
- log.error("Error while parsing inline RequestMap");
- log.error("XML error " + e);
+ initlog.error("Error while parsing inline RequestMap");
+ initlog.error("XML error " + e);
return true;
}
return true;
requestMapDoc = RequestMapDocument.Factory.parse(mapdoc);
} catch (Exception e) {
- log.error("Error while parsing RequestMap file "+uri);
- log.error("XML error " + e);
+ initlog.error("Error while parsing RequestMap file "+uri);
+ initlog.error("XML error " + e);
return true;
}
}
}
-
+ // Generate Map keys for inline plugin configuration Elements
private int inlinenum = 1;
private String genDummyUri() {
return INLINEURN+Integer.toString(inlinenum++);
* query their value directly.
*/
public class ApplicationInfo
- implements EntityLocator, ITrust {
+ implements Metadata, Trust {
private Application applicationConfig;
public Application getApplicationConfig() {
* function in the new interface that will use the new term, but
* it does the same thing.</p>
*
- * @param id ID of the OriginSite entity
+ * @param id ID of the IdP entity
* @return EntityDescriptor metadata object for that site.
*/
- public EntityDescriptor getEntityDescriptor(String id) {
+ public EntityDescriptor lookup(String id, boolean strict) {
Iterator iuris = groupUris.iterator();
while (iuris.hasNext()) {
String uri =(String) iuris.next();
- EntityLocator locator=getMetadataImplementor(uri);
- EntityDescriptor entity = locator.getEntityDescriptor(id);
- if (entity!=null)
+ Metadata locator=getMetadataImplementor(uri);
+ EntityDescriptor entity = locator.lookup(id, strict);
+ if (entity!=null) {
+ reqlog.debug("Metadata.lookup resolved Entity "+ id);
return entity;
+ }
}
+ reqlog.warn("Metadata.lookup failed to resolve Entity "+ id);
return null;
}
-
- /**
- * Convenience function to fulfill Metadata interface contract.
- *
- * @param id ID of OriginSite
- * @return Provider object for that Site.
- */
- public Provider lookup(String id) {
- return getEntityDescriptor(id);
+
+ public EntityDescriptor lookup(Artifact artifact, boolean strict) {
+ Iterator iuris = groupUris.iterator();
+ while (iuris.hasNext()) {
+ String uri =(String) iuris.next();
+ Metadata locator=getMetadataImplementor(uri);
+ EntityDescriptor entity = locator.lookup(artifact, strict);
+ if (entity!=null) {
+ reqlog.debug("Metadata.lookup resolved Artifact "+ artifact);
+ return entity;
+ }
+ }
+ reqlog.warn("Metadata.lookup failed to resolve Artifact "+ artifact);
+ return null;
+ }
+
+ public EntityDescriptor lookup(String id) {
+ return lookup(id,true);
}
-
+
+ public EntityDescriptor lookup(Artifact artifact) {
+ return lookup(artifact,true);
+ }
+
+ public EntityDescriptor getRootEntity() {
+ return null;
+ }
+
+ public EntitiesDescriptor getRootEntities() {
+ return null;
+ }
+
/**
- * Return the current array of objects that implement the ITrust interface
+ * Return the current array of objects that implement the Trust interface
*
- * @return ITrust[]
+ * @return Trust[]
*/
- public ITrust[] getTrustProviders() {
- Iterator iuris = groupUris.iterator();
- int count = groupUris.size();
- ITrust[] trusts = new ITrust[count];
+ public Trust[] getTrustProviders() {
+ Iterator iuris = trustUris.iterator();
+ int count = trustUris.size();
+ if (count==0)
+ return defaultTrust;
+ Trust[] trusts = new Trust[count];
for (int i=0;i<count;i++) {
String uri =(String) iuris.next();
trusts[i]=getTrustImplementor(uri);
* Empty SAML elements get removed from the assertion.
* This can yield an AttributeAssertion with no attributes.
*
- * @param entity Origin site that sent the assertion
* @param assertion SAML Attribute Assertion
+ * @param role Role that issued the assertion
+ * @throws SAMLException Raised if assertion is mangled beyond repair
*/
- void applyAAP(EntityDescriptor entity, SAMLAssertion assertion) {
+ void applyAAP(SAMLAssertion assertion, RoleDescriptor role) throws SAMLException {
// Foreach AAP in the collection
AAP[] providers = getAAPProviders();
+ if (providers.length == 0) {
+ reqlog.info("no filters specified, accepting entire assertion");
+ return;
+ }
for (int i=0;i<providers.length;i++) {
AAP aap = providers[i];
- if (aap.isAnyAttribute())
+ if (aap.anyAttribute()) {
+ reqlog.info("any attribute enabled, accepting entire assertion");
continue;
-
- // Foreach Statement in the Assertion
- Iterator statements = assertion.getStatements();
- int istatement=0;
- while (statements.hasNext()) {
- Object statement = statements.next();
- if (statement instanceof SAMLAttributeStatement) {
- SAMLAttributeStatement attributeStatement =
- (SAMLAttributeStatement) statement;
-
- // Foreach Attribute in the AttributeStatement
- Iterator attributes = attributeStatement.getAttributes();
- int iattribute=0;
- while (attributes.hasNext()) {
- SAMLAttribute attribute =
- (SAMLAttribute) attributes.next();
- String name = attribute.getName();
- String namespace = attribute.getNamespace();
- AttributeRule rule = aap.lookup(name,namespace);
- if (rule==null) {
- // TODO Not sure, but code appears to keep unknown attributes
- log.warn("No rule found for attribute "+name);
- iattribute++;
- continue;
- }
- rule.apply(entity,attribute);
- if (!attribute.getValues().hasNext())
- attributeStatement.removeAttribute(iattribute);
- else
- iattribute++;
-
- }
- if (!attributeStatement.getAttributes().hasNext())
- assertion.removeStatement(istatement);
- else
- istatement++;
- } else {
- istatement++;
+ }
+ }
+
+ // Foreach Statement in the Assertion
+ Iterator statements = assertion.getStatements();
+ int istatement=0;
+ while (statements.hasNext()) {
+ Object statement = statements.next();
+ if (statement instanceof SAMLAttributeStatement) {
+ SAMLAttributeStatement attributeStatement = (SAMLAttributeStatement) statement;
+
+ // Check each attribute, applying any matching rules.
+ Iterator attributes = attributeStatement.getAttributes();
+ int iattribute=0;
+ while (attributes.hasNext()) {
+ SAMLAttribute attribute = (SAMLAttribute) attributes.next();
+ boolean ruleFound = false;
+ for (int i=0;i<providers.length;i++) {
+ AttributeRule rule = providers[i].lookup(attribute.getName(),attribute.getNamespace());
+ if (rule!=null) {
+ ruleFound = true;
+ try {
+ rule.apply(attribute,role);
+ }
+ catch (SAMLException ex) {
+ reqlog.info("no values remain, removing attribute");
+ attributeStatement.removeAttribute(iattribute--);
+ break;
+ }
+ }
+ }
+ if (!ruleFound) {
+ reqlog.warn("no rule found for attribute (" + attribute.getName() + "), filtering it out");
+ attributeStatement.removeAttribute(iattribute--);
+ }
+ iattribute++;
+ }
+
+ try {
+ attributeStatement.checkValidity();
+ istatement++;
+ }
+ catch (SAMLException ex) {
+ // The statement is now defunct.
+ reqlog.info("no attributes remain, removing statement");
+ assertion.removeStatement(istatement);
}
}
}
- }
+
+ // Now see if we trashed it irrevocably.
+ assertion.checkValidity();
+ }
/**
/**
- * Convenience method implementing ITrust.validate() across
+ * Convenience method implementing Trust.validate() across
* the collection of implementing objects. Returns true if
* any Trust implementor approves the signatures in the object.
*
*/
public boolean
validate(
- Iterator revocations, // Currently unused
- ProviderRole role,
- SAMLObject token,
- EntityLocator dummy // "this" is an EntityLocator
+ SAMLSignedObject token,
+ RoleDescriptor role
) {
- // TODO If revocations are supported, "this" will provide them
-
- ITrust[] trustProviders = getTrustProviders();
+
+ Trust[] trustProviders = getTrustProviders();
for (int i=0;i<trustProviders.length;i++) {
- ITrust trust = trustProviders[i];
- if (trust.validate(null,role,token,this))
+ Trust trust = trustProviders[i];
+ if (trust.validate(token,role))
return true;
}
+ reqlog.warn("SAML object failed Trust validation.");
return false;
}
- /**
- * Simpler version of validate that avoids dummy arguments
- *
- * @param role Entity that sent Token (from Metadata)
- * @param token Signed SAMLObject
- * @return
- */
- public boolean validate(ProviderRole role, SAMLObject token) {
- return validate(null,role,token,null);
- }
/**
- * A method of ITrust that we must declare to claim that
- * ApplicationInfo implements ITrust. However, no code in the
- * ServiceProvider calls this (probably an Origin thing).
+ * A method of Trust that we must declare to claim that
+ * ApplicationInfo implements Trust. However, no code in the
+ * ServiceProvider calls this (probably an IdP thing).
*
* @param revocations
* @param role
* @return This dummy always returns false.
*/
- public boolean attach(Iterator revocations, ProviderRole role) {
+ public boolean attach(Iterator revocations, RoleDescriptor role) {
// Unused
return false;
}
-
+
+ public boolean validate(X509Certificate certificateEE, X509Certificate[] certificateChain, RoleDescriptor descriptor) {
+ Trust[] trustProviders = getTrustProviders();
+ for (int i=0;i<trustProviders.length;i++) {
+ Trust trust = trustProviders[i];
+ if (trust.validate(certificateEE,certificateChain,descriptor))
+ return true;
+ }
+ reqlog.warn("X.509 Certificate failed Trust validate");
+ return false;
+ }
+
+ public boolean validate(X509Certificate certificateEE, X509Certificate[] certificateChain, RoleDescriptor descriptor, boolean checkName) {
+ Trust[] trustProviders = getTrustProviders();
+ for (int i=0;i<trustProviders.length;i++) {
+ Trust trust = trustProviders[i];
+ if (trust.validate(certificateEE,certificateChain,descriptor,checkName))
+ return true;
+ }
+ reqlog.warn("X.509 Certificate failed Trust validate");
+ return false;
+ }
+
+ public String getProviderId() {
+ String entityId = this.applicationConfig.getProviderId();
+ if (entityId==null && this!=defaultApplicationInfo) {
+ entityId = defaultApplicationInfo.getProviderId();
+ }
+ return entityId;
+ }
}
super();
}
}
+
+
+
+ public Credentials getCredentials() {
+ return credentials;
+ }
}