private static Logger log = Logger.getLogger(AAConfig.class.getName());
private String resolverConfig = "/conf/resolver.xml";
+ private boolean passThruErrors = false;
public AAConfig(Element config) throws ShibbolethConfigurationException {
//Global Pass thru error setting
String attribute = ((Element) config).getAttribute("passThruErros");
- if (attribute == null || attribute.equals("")) {
- properties.setProperty("edu.internet2.middleware.shibboleth.aa.AAServlet.passThruErrors", "false");
- } else {
- if (!attribute.equalsIgnoreCase("TRUE") && !attribute.equalsIgnoreCase("FALSE")) {
- log.error("passThrue errors is a boolean property.");
- properties.setProperty("edu.internet2.middleware.shibboleth.aa.AAServlet.passThruErrors", "false");
- } else {
- properties.setProperty("edu.internet2.middleware.shibboleth.aa.AAServlet.passThruErrors", attribute);
- }
+ if (attribute != null && !attribute.equals("")) {
+ passThruErrors = Boolean.getBoolean(attribute);
}
}
return resolverConfig;
}
+ public boolean passThruErrors() {
+ return passThruErrors;
+ }
+
}
--- /dev/null
+/*
+ * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation
+ * for Advanced Internet Development, Inc. All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.internet2.middleware.shibboleth.aa;
+
+import edu.internet2.middleware.shibboleth.common.RelyingParty;
+
+/**
+ * @author Walter Hoehn
+ */
+public interface AARelyingParty extends RelyingParty {
+
+ public boolean passThruErrors();
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation
+ * for Advanced Internet Development, Inc. All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.internet2.middleware.shibboleth.aa;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import edu.internet2.middleware.shibboleth.common.RelyingParty;
+import edu.internet2.middleware.shibboleth.common.ServiceProviderMapper;
+import edu.internet2.middleware.shibboleth.common.ServiceProviderMapperException;
+import edu.internet2.middleware.shibboleth.common.ShibbolethOriginConfig;
+
+/**
+ * @author Walter Hoehn
+ */
+public class AAServiceProviderMapper extends ServiceProviderMapper {
+
+ private static Logger log = Logger.getLogger(AAServiceProviderMapper.class.getName());
+ private AAConfig configuration;
+
+ public AAServiceProviderMapper(Element rawConfig, AAConfig configuration) throws ServiceProviderMapperException {
+
+ this.configuration = configuration;
+
+ NodeList itemElements =
+ rawConfig.getElementsByTagNameNS(ShibbolethOriginConfig.originConfigNamespace, "RelyingParty");
+
+ for (int i = 0; i < itemElements.getLength(); i++) {
+ addRelyingParty((Element) itemElements.item(i));
+ }
+
+ verifyDefaultParty(configuration);
+ }
+
+ private void addRelyingParty(Element e) throws ServiceProviderMapperException {
+
+ log.debug("Found a Relying Party.");
+ try {
+ if (e.getLocalName().equals("RelyingParty")) {
+ RelyingParty party = new AARelyingPartyImpl(e, configuration);
+ log.debug("Relying Party (" + party.getName() + ") loaded.");
+ relyingParties.put(party.getName(), party);
+ }
+ } catch (ServiceProviderMapperException exc) {
+ log.error("Encountered an error while attempting to load Relying Party configuration. Skipping...");
+ }
+ }
+
+ public AARelyingParty getRelyingParty(String providerIdFromTarget) {
+ return (AARelyingParty) getRelyingPartyImpl(providerIdFromTarget);
+ }
+
+ class AARelyingPartyImpl extends BaseRelyingPartyImpl {
+
+ private AAConfig aaConfig;
+ private boolean overridenPassThruErrors;
+ private boolean passThruIsOverriden;
+
+ public AARelyingPartyImpl(Element partyConfig, AAConfig globalConfig) throws ServiceProviderMapperException {
+ super(partyConfig);
+
+ aaConfig = globalConfig;
+
+ String attribute = ((Element) partyConfig).getAttribute("passThruErros");
+ if (attribute != null && !attribute.equals("")) {
+ log.debug("Overriding passThruErrors for Relying Pary (" + name + ") with (" + attribute + ").");
+ overridenPassThruErrors = Boolean.getBoolean(attribute);
+ passThruIsOverriden = true;
+ }
+
+ identityProvider = new RelyingPartyIdentityProvider(overridenOriginProviderId, null);
+ }
+
+ public boolean passThruErrors() {
+ if (passThruIsOverriden) {
+ return overridenPassThruErrors;
+ } else {
+ return aaConfig.passThruErrors();
+ }
+ }
+
+ }
+
+ protected ShibbolethOriginConfig getOriginConfig() {
+ return configuration;
+ }
+}
import edu.internet2.middleware.shibboleth.common.OriginComponent;
import edu.internet2.middleware.shibboleth.common.RelyingParty;
import edu.internet2.middleware.shibboleth.common.SAMLBindingFactory;
-import edu.internet2.middleware.shibboleth.common.ServiceProviderMapper;
import edu.internet2.middleware.shibboleth.common.ServiceProviderMapperException;
import edu.internet2.middleware.shibboleth.common.ShibResource;
import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
private NameMapper nameMapper;
private SAMLBinding binding;
private static Logger transactionLog = Logger.getLogger("Shibboleth-TRANSACTION");
- private ServiceProviderMapper targetMapper;
+ private AAServiceProviderMapper targetMapper;
private static Logger log = Logger.getLogger(AAServlet.class.getName());
//Load relying party config
try {
- targetMapper = new ServiceProviderMapper(parser.getDocument().getDocumentElement(), configuration);
+ targetMapper = new AAServiceProviderMapper(parser.getDocument().getDocumentElement(), configuration);
} catch (ServiceProviderMapperException e) {
log.error("Could not load origin configuration: " + e);
throw new ShibbolethConfigurationException("Could not load origin configuration.");
MDC.put("remoteAddr", req.getRemoteAddr());
log.info("Handling request.");
- RelyingParty relyingParty = null;
+ AARelyingParty relyingParty = null;
//Parse SOAP request
SAMLRequest samlRequest = null;
{
SAMLException.REQUESTER,
new QName(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS, "InvalidHandle")};
- if (relyingParty
- .getConfigProperty("edu.internet2.middleware.shibboleth.aa.AAServlet.passThruErrors")
- .equals("true")) {
+ if (relyingParty.passThruErrors()) {
sendFailure(
resp,
samlRequest,
} catch (Exception e) {
log.error("Error while processing request: " + e);
try {
- if (relyingParty != null
- && relyingParty.getConfigProperty(
- "edu.internet2.middleware.shibboleth.aa.AAServlet.passThruErrors").equals(
- "true")) {
+ if (relyingParty != null && relyingParty.passThruErrors()) {
sendFailure(
resp,
samlRequest,
new SAMLException(SAMLException.RESPONDER, "General error processing request.", e));
- } else if (
- configuration.getConfigProperty(
- "edu.internet2.middleware.shibboleth.aa.AAServlet.passThruErrors").equals(
- "true")) {
+ } else if (configuration.passThruErrors()) {
sendFailure(
resp,
samlRequest,
public interface RelyingParty extends ServiceProvider {
public String getName();
-
- public String getConfigProperty(String key);
-
- public boolean isLegacyProvider();
-
- public String getHSNameFormatId();
-
+ public String getProviderId();
public IdentityProvider getIdentityProvider();
}
import java.util.HashMap;
import java.util.Map;
-import java.util.Properties;
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import edu.internet2.middleware.shibboleth.hs.HSNameMapper;
/**
* @author Walter Hoehn
*
*/
-public class ServiceProviderMapper {
-
- private static Logger log = Logger.getLogger(ShibbolethOriginConfig.class.getName());
- private ShibbolethOriginConfig configuration;
- private Credentials credentials;
- private HSNameMapper nameMapper;
- private Map relyingParties = new HashMap();
-
- public ServiceProviderMapper(
- Element rawConfig,
- ShibbolethOriginConfig configuration,
- Credentials credentials,
- HSNameMapper nameMapper)
- throws ServiceProviderMapperException {
-
- this.configuration = configuration;
- this.credentials = credentials;
- this.nameMapper = nameMapper;
-
- NodeList itemElements =
- rawConfig.getElementsByTagNameNS(ShibbolethOriginConfig.originConfigNamespace, "RelyingParty");
-
- for (int i = 0; i < itemElements.getLength(); i++) {
- addHSRelyingParty((Element) itemElements.item(i));
- }
-
- verifyDefaultParty(configuration);
- }
-
- public ServiceProviderMapper(Element rawConfig, ShibbolethOriginConfig configuration)
- throws ServiceProviderMapperException {
+public abstract class ServiceProviderMapper {
- this.configuration = configuration;
+ private static Logger log = Logger.getLogger(ServiceProviderMapper.class.getName());
+ protected Map relyingParties = new HashMap();
- NodeList itemElements =
- rawConfig.getElementsByTagNameNS(ShibbolethOriginConfig.originConfigNamespace, "RelyingParty");
-
- for (int i = 0; i < itemElements.getLength(); i++) {
- addAARelyingParty((Element) itemElements.item(i));
- }
-
- verifyDefaultParty(configuration);
- }
+ protected abstract ShibbolethOriginConfig getOriginConfig();
- private void verifyDefaultParty(ShibbolethOriginConfig configuration) throws ServiceProviderMapperException {
+ protected void verifyDefaultParty(ShibbolethOriginConfig configuration) throws ServiceProviderMapperException {
//Verify we have a proper default party
- String defaultParty =
- configuration.getConfigProperty(
- "edu.internet2.middleware.shibboleth.common.RelyingParty.defaultRelyingParty");
+ System.err.println("Walter: " + configuration.getDefaultRelyingPartyName());
+ String defaultParty = configuration.getDefaultRelyingPartyName();
if (defaultParty == null || defaultParty.equals("")) {
if (relyingParties.size() != 1) {
log.error(
}
}
- private void addHSRelyingParty(Element e) throws ServiceProviderMapperException {
-
- log.debug("Found a Relying Party.");
- try {
- if (e.getLocalName().equals("RelyingParty")) {
- RelyingParty party = new RelyingPartyImpl(e, configuration, credentials, nameMapper);
- log.debug("Relying Party (" + party.getName() + ") loaded.");
- relyingParties.put(party.getName(), party);
- }
- } catch (ServiceProviderMapperException exc) {
- log.error("Encountered an error while attempting to load Relying Party configuration. Skipping...");
- }
- }
-
- private void addAARelyingParty(Element e) throws ServiceProviderMapperException {
-
- log.debug("Found a Relying Party.");
- try {
- if (e.getLocalName().equals("RelyingParty")) {
- RelyingParty party = new RelyingPartyImpl(e, configuration);
- log.debug("Relying Party (" + party.getName() + ") loaded.");
- relyingParties.put(party.getName(), party);
- }
- } catch (ServiceProviderMapperException exc) {
- log.error("Encountered an error while attempting to load Relying Party configuration. Skipping...");
- }
- }
- public RelyingParty getRelyingParty(String providerIdFromTarget) {
-
- //If the target did not send a Provider Id, then assume it is a Shib
- // 1.1 or older target
- if (providerIdFromTarget == null || providerIdFromTarget.equals("")) {
- log.info("Request is from legacy shib target. Selecting default Relying Party.");
- return new LegacyWrapper(getDefaultRelyingPatry());
- }
+ protected RelyingParty getRelyingPartyImpl(String providerIdFromTarget) {
//Look for a configuration for the specific relying party
if (relyingParties.containsKey(providerIdFromTarget)) {
return null;
}
- private RelyingParty getDefaultRelyingPatry() {
+ protected RelyingParty getDefaultRelyingPatry() {
//If there is no explicit default, pick the single configured Relying
// Party
- String defaultParty =
- configuration.getConfigProperty(
- "edu.internet2.middleware.shibboleth.common.RelyingParty.defaultRelyingParty");
+ String defaultParty = getOriginConfig().getDefaultRelyingPartyName();
if (defaultParty == null || defaultParty.equals("")) {
return (RelyingParty) relyingParties.values().iterator().next();
}
return (RelyingParty) relyingParties.get(defaultParty);
}
- class RelyingPartyImpl implements RelyingParty {
+ protected abstract class BaseRelyingPartyImpl implements RelyingParty {
- protected ShibbolethOriginConfig originConfig;
- protected Properties partyOverrides = new Properties();
protected RelyingPartyIdentityProvider identityProvider;
protected String name;
- protected String hsNameFormatId;
-
- /**
- * Constructor for use by Handle Service
- */
- public RelyingPartyImpl(
- Element partyConfig,
- ShibbolethOriginConfig globalConfig,
- Credentials credentials,
- HSNameMapper nameMapper)
- throws ServiceProviderMapperException {
-
- this(partyConfig, globalConfig);
-
- //Load a credential for signing
- String credentialName = ((Element) partyConfig).getAttribute("signingCredential");
- Credential credential = credentials.getCredential(credentialName);
-
- if (credential == null) {
- if (credentialName == null || credentialName.equals("")) {
- log.error(
- "Relying Party credential not set. Add a (signingCredential) attribute to <RelyingParty>.");
- throw new ServiceProviderMapperException("Required configuration not specified.");
- } else {
- log.error(
- "Relying Party credential not set. Add a (signingCredential) attribute to <RelyingParty>.");
- throw new ServiceProviderMapperException("Required configuration not specified.");
- }
- }
-
- //Load and verify the name format that the HS should use in
- //assertions for this RelyingParty
- NodeList hsNameFormats =
- ((Element) partyConfig).getElementsByTagNameNS(
- ShibbolethOriginConfig.originConfigNamespace,
- "HSNameFormat");
- //If no specification. Make sure we have a default mapping
- if (hsNameFormats.getLength() < 1) {
- if (nameMapper.getNameIdentifierMappingById(null) == null) {
- log.error("Relying Party HS Name Format not set. Add a <HSNameFormat> element to <RelyingParty>.");
- throw new ServiceProviderMapperException("Required configuration not specified.");
- }
-
- } else {
- //We do have a specification, so make sure it points to a
- // valid Name Mapping
- if (hsNameFormats.getLength() > 1) {
- log.warn(
- "Found multiple HSNameFormat specifications for Relying Party ("
- + name
- + "). Ignoring all but the first.");
- }
-
- String hsNameFormatId = ((Element) hsNameFormats.item(0)).getAttribute("nameMapping");
- if (hsNameFormatId == null || hsNameFormatId.equals("")) {
- log.error("HS Name Format mapping not set. Add a (nameMapping) attribute to <HSNameFormat>.");
- throw new ServiceProviderMapperException("Required configuration not specified.");
- }
-
- if (nameMapper.getNameIdentifierMappingById(hsNameFormatId) == null) {
- log.error("Relying Party HS Name Format refers to a name mapping that is not loaded.");
- throw new ServiceProviderMapperException("Required configuration not specified.");
- }
- }
-
- //Global overrides
- String attribute = ((Element) partyConfig).getAttribute("AAUrl");
- if (attribute != null && !attribute.equals("")) {
- log.debug("Overriding AAUrl for Relying Pary (" + name + ") with (" + attribute + ").");
- partyOverrides.setProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.AAUrl", attribute);
- }
-
- attribute = ((Element) partyConfig).getAttribute("defaultAuthMethod");
- if (attribute != null && !attribute.equals("")) {
- log.debug("Overriding defaultAuthMethod for Relying Pary (" + name + ") with (" + attribute + ").");
- partyOverrides.setProperty(
- "edu.internet2.middleware.shibboleth.hs.HandleServlet.defaultAuthMethod",
- attribute);
- }
-
- identityProvider =
- new RelyingPartyIdentityProvider(
- getConfigProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.providerId"),
- credential);
- }
+ protected String overridenOriginProviderId;
/**
- * Shared constructor
+ * Shared construction
*/
- public RelyingPartyImpl(Element partyConfig, ShibbolethOriginConfig globalConfig)
- throws ServiceProviderMapperException {
-
- //Use global config for defaults
- this.originConfig = globalConfig;
+ public BaseRelyingPartyImpl(Element partyConfig) throws ServiceProviderMapperException {
//Get party name
name = ((Element) partyConfig).getAttribute("name");
String attribute = ((Element) partyConfig).getAttribute("providerId");
if (attribute != null && !attribute.equals("")) {
log.debug("Overriding providerId for Relying Pary (" + name + ") with (" + attribute + ").");
- partyOverrides.setProperty(
- "edu.internet2.middleware.shibboleth.hs.HandleServlet.providerId",
- attribute);
- }
-
- attribute = ((Element) partyConfig).getAttribute("passThruErrors");
- if (attribute != null && !attribute.equals("")) {
- if (!attribute.equalsIgnoreCase("TRUE") && !attribute.equalsIgnoreCase("FALSE")) {
- log.error("passThrue errors is a boolean property.");
- } else {
- log.debug("Overriding passThruErrors for Relying Pary (" + name + ") with (" + attribute + ").");
- partyOverrides.setProperty(
- "edu.internet2.middleware.shibboleth.aa.AAServlet.passThruErrors",
- attribute);
- }
+ overridenOriginProviderId = attribute;
}
- identityProvider =
- new RelyingPartyIdentityProvider(
- getConfigProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.providerId"),
- null);
-
}
+
public String getProviderId() {
return name;
}
return name;
}
- public boolean isLegacyProvider() {
- return false;
- }
-
- public String getConfigProperty(String key) {
- if (partyOverrides.containsKey(key)) {
- return partyOverrides.getProperty(key);
- }
- return originConfig.getConfigProperty(key);
- }
-
- public String getHSNameFormatId() {
- return null;
- }
-
public IdentityProvider getIdentityProvider() {
return identityProvider;
}
- class RelyingPartyIdentityProvider implements IdentityProvider {
+ protected class RelyingPartyIdentityProvider implements IdentityProvider {
private String providerId;
private Credential responseSigningCredential;
- RelyingPartyIdentityProvider(String providerId, Credential responseSigningCred) {
+ public RelyingPartyIdentityProvider(String providerId, Credential responseSigningCred) {
this.providerId = providerId;
this.responseSigningCredential = responseSigningCred;
}
}
}
+ //TODO this will break because it doesn't implement both interfaces
class RelyingPartyGroupWrapper implements RelyingParty {
private RelyingParty wrapped;
return wrapped.getName();
}
- public String getConfigProperty(String key) {
- return wrapped.getConfigProperty(key);
- }
-
public boolean isLegacyProvider() {
return false;
}
- public String getHSNameFormatId() {
- return wrapped.getHSNameFormatId();
- }
-
public IdentityProvider getIdentityProvider() {
return wrapped.getIdentityProvider();
}
}
}
- class UnknownProviderWrapper implements RelyingParty {
- private RelyingParty wrapped;
+ //TODO this will break because it doesn't implement both interfaces
+ protected class UnknownProviderWrapper implements RelyingParty {
+ protected RelyingParty wrapped;
- UnknownProviderWrapper(RelyingParty wrapped) {
+ protected UnknownProviderWrapper(RelyingParty wrapped) {
this.wrapped = wrapped;
}
return wrapped.getName();
}
- public String getConfigProperty(String key) {
- return wrapped.getConfigProperty(key);
- }
-
- public boolean isLegacyProvider() {
- return wrapped.isLegacyProvider();
- }
-
- public String getHSNameFormatId() {
- return wrapped.getHSNameFormatId();
- }
-
public IdentityProvider getIdentityProvider() {
return wrapped.getIdentityProvider();
}
}
}
- class LegacyWrapper extends UnknownProviderWrapper {
-
- LegacyWrapper(RelyingParty wrapped) {
- super(wrapped);
- }
- public boolean isLegacyProvider() {
- return true;
- }
- }
}
import org.opensaml.TrustException;
import org.w3c.dom.Document;
+import edu.internet2.middleware.shibboleth.hs.HSRelyingParty;
+
/**
* Basic Shibboleth POST browser profile implementation with basic support for
* signing
*/
public SAMLResponse prepare(
String recipient,
- RelyingParty relyingParty,
+ HSRelyingParty relyingParty,
SAMLNameIdentifier nameId,
String subjectIP,
String authMethod,
*/
package edu.internet2.middleware.shibboleth.common;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Properties;
-
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
*/
public abstract class ShibbolethOriginConfig {
+ private String defaultRelyingPartyName;
+ private String providerId;
public static final String originConfigNamespace = "urn:mace:shibboleth:origin:1.0";
private static Logger log = Logger.getLogger(ShibbolethOriginConfig.class.getName());
- protected Properties properties = new Properties();
public ShibbolethOriginConfig(Element config) throws ShibbolethConfigurationException {
log.debug("Loading global configuration properties.");
- String attribute = ((Element) config).getAttribute("providerId");
- if (attribute == null || attribute.equals("")) {
+ //Global providerId
+ String providerId = ((Element) config).getAttribute("providerId");
+ if (providerId == null || providerId.equals("")) {
log.error("Global providerId not set. Add a (providerId) attribute to <ShibbolethOriginConfig>.");
throw new ShibbolethConfigurationException("Required configuration not specified.");
- } //TODO should not be under hs namespace
- properties.setProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.providerId", attribute);
+ }
- attribute = ((Element) config).getAttribute("defaultRelyingParty");
- if (attribute == null || attribute.equals("")) {
- log.error("Global providerId not set. Add a (defaultRelyingParty) attribute to <ShibbolethOriginConfig>.");
+ //Default Relying Party
+ String defaultRelyingPartyName = ((Element) config).getAttribute("defaultRelyingParty");
+ if (defaultRelyingPartyName == null || defaultRelyingPartyName.equals("")) {
+ log.error("Default Relying Party not set. Add a (defaultRelyingParty) attribute to <ShibbolethOriginConfig>.");
throw new ShibbolethConfigurationException("Required configuration not specified.");
}
- properties.setProperty(
- "edu.internet2.middleware.shibboleth.common.RelyingParty.defaultRelyingParty",
- attribute);
-
+ log.debug("Default Relying Party: (" + getDefaultRelyingPartyName() + ").");
}
- protected void dumpPropertiesToLog() {
- if (log.isDebugEnabled()) {
- ByteArrayOutputStream debugStream = new ByteArrayOutputStream();
- PrintStream debugPrinter = new PrintStream(debugStream);
- properties.list(debugPrinter);
- log.debug(
- "Global Runtime configuration parameters: "
- + System.getProperty("line.separator")
- + debugStream.toString());
- try {
- debugStream.close();
- } catch (IOException e) {
- log.error("Encountered a problem cleaning up resources: could not close debug stream.");
- }
- }
+ public String getProviderId() {
+ return providerId;
}
- public String getConfigProperty(String key) {
- return properties.getProperty(key);
+ public String getDefaultRelyingPartyName() {
+ return defaultRelyingPartyName;
}
}
package edu.internet2.middleware.shibboleth.hs;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
private int maxThreads = 5;
private String authHeaderName = "REMOTE_USER";
+ private URI defaultAuthMethod;
+ private URL AAUrl;
public HSConfig(Element config) throws ShibbolethConfigurationException {
super(config);
String attribute = ((Element) config).getAttribute("AAUrl");
if (attribute == null || attribute.equals("")) {
- log.error("Global providerId not set. Add a (AAUrl) attribute to <ShibbolethOriginConfig>.");
+ log.error("Global Attribute Authority URL not set. Add an (AAUrl) attribute to <ShibbolethOriginConfig>.");
throw new ShibbolethConfigurationException("Required configuration not specified.");
}
- properties.setProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.AAUrl", attribute);
+ try {
+ AAUrl = new URL(attribute);
+ } catch (MalformedURLException e) {
+ log.error("(AAUrl) attribute to is not a valid URL.");
+ throw new ShibbolethConfigurationException("Required configuration is invalid.");
+ }
attribute = ((Element) config).getAttribute("defaultAuthMethod");
if (attribute == null || attribute.equals("")) {
- properties.setProperty(
- "edu.internet2.middleware.shibboleth.hs.HandleServlet.defaultAuthMethod",
- "urn:oasis:names:tc:SAML:1.0:am:unspecified");
+ try {
+ defaultAuthMethod = new URI("urn:oasis:names:tc:SAML:1.0:am:unspecified");
+ } catch (URISyntaxException e1) {
+ //Shouldn't happen
+ throw new ShibbolethConfigurationException("Default Auth Method URI could not be constructed.");
+ }
+ }
+ try {
+ defaultAuthMethod = new URI(attribute);
+ } catch (URISyntaxException e1) {
+ log.error("(defaultAuthMethod) attribute to is not a valid URI.");
+ throw new ShibbolethConfigurationException("Required configuration is invalid.");
}
- properties.setProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.defaultAuthMethod", attribute);
-
}
public int getMaxThreads() {
public String getAuthHeaderName() {
return authHeaderName;
}
+
+ public URI getDefaultAuthMethod() {
+ return defaultAuthMethod;
+ }
+
+ public URL getAAUrl() {
+ return AAUrl;
+ }
}
--- /dev/null
+/*
+ * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation
+ * for Advanced Internet Development, Inc. All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.internet2.middleware.shibboleth.hs;
+
+import java.net.URI;
+import java.net.URL;
+
+import edu.internet2.middleware.shibboleth.common.RelyingParty;
+
+/**
+ * @author Walter Hoehn
+ */
+public interface HSRelyingParty extends RelyingParty {
+
+ public String getHSNameFormatId();
+ public boolean isLegacyProvider();
+ public URL getAAUrl();
+ public URI getDefaultAuthMethod();
+}
--- /dev/null
+/*
+ * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation for Advanced Internet Development, Inc.
+ * All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the distribution, if any, must include the
+ * following acknowledgment: "This product includes software developed by the University Corporation for Advanced
+ * Internet Development <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement may appear in the
+ * software itself, if and wherever such third-party acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor Internet2, nor the University Corporation for
+ * Advanced Internet Development, Inc., nor UCAID may be used to endorse or promote products derived from this software
+ * without specific prior written permission. For written permission, please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2, UCAID, or the University Corporation
+ * for Advanced Internet Development, nor may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND WITH ALL FAULTS. ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK OF SATISFACTORY QUALITY, PERFORMANCE,
+ * ACCURACY, AND EFFORT IS WITH LICENSEE. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.internet2.middleware.shibboleth.hs;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import edu.internet2.middleware.shibboleth.common.Credential;
+import edu.internet2.middleware.shibboleth.common.Credentials;
+import edu.internet2.middleware.shibboleth.common.RelyingParty;
+import edu.internet2.middleware.shibboleth.common.ServiceProviderMapper;
+import edu.internet2.middleware.shibboleth.common.ServiceProviderMapperException;
+import edu.internet2.middleware.shibboleth.common.ShibbolethOriginConfig;
+
+/**
+ * @author Walter Hoehn
+ */
+public class HSServiceProviderMapper extends ServiceProviderMapper {
+
+ private static Logger log = Logger.getLogger(HSServiceProviderMapper.class.getName());
+ private HSConfig configuration;
+ private Credentials credentials;
+ private HSNameMapper nameMapper;
+
+ public HSServiceProviderMapper(
+ Element rawConfig,
+ HSConfig configuration,
+ Credentials credentials,
+ HSNameMapper nameMapper)
+ throws ServiceProviderMapperException {
+System.err.println("Walter 2: " + configuration.getDefaultRelyingPartyName());
+ this.configuration = configuration;
+ this.credentials = credentials;
+ this.nameMapper = nameMapper;
+
+ NodeList itemElements =
+ rawConfig.getElementsByTagNameNS(ShibbolethOriginConfig.originConfigNamespace, "RelyingParty");
+
+ for (int i = 0; i < itemElements.getLength(); i++) {
+ addRelyingParty((Element) itemElements.item(i));
+ }
+
+ verifyDefaultParty(configuration);
+ }
+
+ private void addRelyingParty(Element e) throws ServiceProviderMapperException {
+
+ log.debug("Found a Relying Party.");
+ try {
+ if (e.getLocalName().equals("RelyingParty")) {
+ RelyingParty party = new HSRelyingPartyImpl(e, configuration, credentials, nameMapper);
+ log.debug("Relying Party (" + party.getName() + ") loaded.");
+ relyingParties.put(party.getName(), party);
+ }
+ } catch (ServiceProviderMapperException exc) {
+ log.error("Encountered an error while attempting to load Relying Party configuration. Skipping...");
+ }
+ }
+
+ public HSRelyingParty getRelyingParty(String providerIdFromTarget) {
+
+ //If the target did not send a Provider Id, then assume it is a Shib
+ // 1.1 or older target
+ if (providerIdFromTarget == null || providerIdFromTarget.equals("")) {
+ log.info("Request is from legacy shib target. Selecting default Relying Party.");
+ return new LegacyWrapper((HSRelyingParty) getDefaultRelyingPatry());
+ }
+
+ return (HSRelyingParty) getRelyingPartyImpl(providerIdFromTarget);
+ }
+ class HSRelyingPartyImpl extends BaseRelyingPartyImpl {
+
+ private URL overridenAAUrl;
+ private URI overridenDefaultAuthMethod;
+ protected String hsNameFormatId;
+ private HSConfig configuration;
+
+ HSRelyingPartyImpl(
+ Element partyConfig,
+ HSConfig globalConfig,
+ Credentials credentials,
+ HSNameMapper nameMapper)
+ throws ServiceProviderMapperException {
+
+ super(partyConfig);
+
+ configuration = globalConfig;
+
+ //Load a credential for signing
+ String credentialName = ((Element) partyConfig).getAttribute("signingCredential");
+ Credential credential = credentials.getCredential(credentialName);
+
+ if (credential == null) {
+ if (credentialName == null || credentialName.equals("")) {
+ log.error(
+ "Relying Party credential not set. Add a (signingCredential) attribute to <RelyingParty>.");
+ throw new ServiceProviderMapperException("Required configuration not specified.");
+ } else {
+ log.error(
+ "Relying Party credential not set. Add a (signingCredential) attribute to <RelyingParty>.");
+ throw new ServiceProviderMapperException("Required configuration not specified.");
+ }
+ }
+
+ //Load and verify the name format that the HS should use in
+ //assertions for this RelyingParty
+ NodeList hsNameFormats =
+ ((Element) partyConfig).getElementsByTagNameNS(
+ ShibbolethOriginConfig.originConfigNamespace,
+ "HSNameFormat");
+ //If no specification. Make sure we have a default mapping
+ if (hsNameFormats.getLength() < 1) {
+ if (nameMapper.getNameIdentifierMappingById(null) == null) {
+ log.error("Relying Party HS Name Format not set. Add a <HSNameFormat> element to <RelyingParty>.");
+ throw new ServiceProviderMapperException("Required configuration not specified.");
+ }
+
+ } else {
+ //We do have a specification, so make sure it points to a
+ // valid Name Mapping
+ if (hsNameFormats.getLength() > 1) {
+ log.warn(
+ "Found multiple HSNameFormat specifications for Relying Party ("
+ + name
+ + "). Ignoring all but the first.");
+ }
+
+ String hsNameFormatId = ((Element) hsNameFormats.item(0)).getAttribute("nameMapping");
+ if (hsNameFormatId == null || hsNameFormatId.equals("")) {
+ log.error("HS Name Format mapping not set. Add a (nameMapping) attribute to <HSNameFormat>.");
+ throw new ServiceProviderMapperException("Required configuration not specified.");
+ }
+
+ if (nameMapper.getNameIdentifierMappingById(hsNameFormatId) == null) {
+ log.error("Relying Party HS Name Format refers to a name mapping that is not loaded.");
+ throw new ServiceProviderMapperException("Required configuration not specified.");
+ }
+ }
+
+ //Global overrides
+ String attribute = ((Element) partyConfig).getAttribute("AAUrl");
+ if (attribute != null && !attribute.equals("")) {
+ log.debug("Overriding AAUrl for Relying Pary (" + name + ") with (" + attribute + ").");
+ try {
+ overridenAAUrl = new URL(attribute);
+ } catch (MalformedURLException e) {
+ log.error("(AAUrl) attribute to is not a valid URL.");
+ throw new ServiceProviderMapperException("Configuration is invalid.");
+ }
+ }
+
+ attribute = ((Element) partyConfig).getAttribute("defaultAuthMethod");
+ if (attribute != null && !attribute.equals("")) {
+ log.debug("Overriding defaultAuthMethod for Relying Pary (" + name + ") with (" + attribute + ").");
+ try {
+ overridenDefaultAuthMethod = new URI(attribute);
+ } catch (URISyntaxException e1) {
+ log.error("(defaultAuthMethod) attribute to is not a valid URI.");
+ throw new ServiceProviderMapperException("Configuration is invalid.");
+ }
+ }
+
+ identityProvider = new RelyingPartyIdentityProvider(overridenOriginProviderId, credential);
+ }
+
+ public boolean isLegacyProvider() {
+ return false;
+ }
+
+ public String getHSNameFormatId() {
+ return hsNameFormatId;
+ }
+
+ public URI getDefaultAuthMethod() {
+
+ if (overridenDefaultAuthMethod != null) {
+ return overridenDefaultAuthMethod;
+ } else {
+ return configuration.getDefaultAuthMethod();
+ }
+ }
+
+ public URL getAAUrl() {
+ if (overridenAAUrl != null) {
+ return overridenAAUrl;
+ } else {
+ return configuration.getAAUrl();
+ }
+ }
+ }
+
+ class LegacyWrapper extends UnknownProviderWrapper implements HSRelyingParty {
+
+ LegacyWrapper(HSRelyingParty wrapped) {
+ super(wrapped);
+ }
+ public boolean isLegacyProvider() {
+ return true;
+ }
+
+ public String getHSNameFormatId() {
+ return ((HSRelyingParty) wrapped).getHSNameFormatId();
+ }
+
+ public URL getAAUrl() {
+ return ((HSRelyingParty) wrapped).getAAUrl();
+ }
+
+ public URI getDefaultAuthMethod() {
+ return ((HSRelyingParty) wrapped).getDefaultAuthMethod();
+ }
+ }
+
+ protected ShibbolethOriginConfig getOriginConfig() {
+ return configuration;
+ }
+
+}
import edu.internet2.middleware.shibboleth.common.NameIdentifierMapping;
import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
import edu.internet2.middleware.shibboleth.common.OriginComponent;
-import edu.internet2.middleware.shibboleth.common.RelyingParty;
-import edu.internet2.middleware.shibboleth.common.ServiceProviderMapper;
import edu.internet2.middleware.shibboleth.common.ServiceProviderMapperException;
import edu.internet2.middleware.shibboleth.common.ShibPOSTProfile;
import edu.internet2.middleware.shibboleth.common.ShibResource;
private Credentials credentials;
private HSNameMapper nameMapper;
private ShibPOSTProfile postProfile = new ShibPOSTProfile();
- private ServiceProviderMapper targetMapper;
+ private HSServiceProviderMapper targetMapper;
protected void loadConfiguration() throws ShibbolethConfigurationException {
//Load global configuration properties
configuration = new HSConfig(parser.getDocument().getDocumentElement());
+ System.out.println("Walter 3: " + configuration.getDefaultRelyingPartyName());
//Load signing credentials
NodeList itemElements =
//Load relying party config
try {
targetMapper =
- new ServiceProviderMapper(
+ new HSServiceProviderMapper(
parser.getDocument().getDocumentElement(),
configuration,
credentials,
req.setAttribute("shire", req.getParameter("shire"));
req.setAttribute("target", req.getParameter("target"));
- RelyingParty relyingParty = targetMapper.getRelyingParty(req.getParameter("providerId"));
+ HSRelyingParty relyingParty = targetMapper.getRelyingParty(req.getParameter("providerId"));
String username =
configuration.getAuthHeaderName().equalsIgnoreCase("REMOTE_USER")
String authenticationMethod = req.getHeader("SAMLAuthenticationMethod");
if (authenticationMethod == null || authenticationMethod.equals("")) {
- authenticationMethod =
- relyingParty.getConfigProperty(
- "edu.internet2.middleware.shibboleth.hs.HandleServlet.defaultAuthMethod");
+ authenticationMethod = relyingParty.getDefaultAuthMethod().toString();
log.debug(
"User was authenticated via the default method for this relying party ("
+ authenticationMethod
}
protected byte[] generateAssertion(
- RelyingParty relyingParty,
+ HSRelyingParty relyingParty,
SAMLNameIdentifier nameId,
String shireURL,
String clientAddress,
SAMLAuthorityBinding binding =
new SAMLAuthorityBinding(
SAMLBinding.SAML_SOAP_HTTPS,
- relyingParty.getConfigProperty("edu.internet2.middleware.shibboleth.hs.HandleServlet.AAUrl"),
+ relyingParty.getAAUrl().toString(),
new QName(org.opensaml.XML.SAMLP_NS, "AttributeQuery"));
//TODO Scott mentioned the clientAddress should be optional at some