public interface RelyingParty extends ServiceProvider {
/**
- * Returns the name of the relying party. If the relying party is a Shibboleth SP (not a group), this
- * function returns the same thing as {@link #getProviderId}.
+ * Returns the name of the relying party. If the relying party is a Shibboleth SP (not a group), this function
+ * returns the same thing as {@link #getProviderId}.
*
* @return name of the relying party
*/
* A boolean indication of whether internal errors should be transmitted to this {@link RelyingParty}
*/
public boolean passThruErrors();
+
+ /**
+ * A boolean indication of whether attributes should be pushed without regard for the profile (POST vs. Artifact).
+ * This should be be mutually exclusive with forceAttributeNoPush().
+ */
+ public boolean forceAttributePush();
+
+ /**
+ * A boolean indication of whether attributes should be NOT pushed without regard for the profile (POST vs.
+ * Artifact).
+ */
+ public boolean forceAttributeNoPush();
}
verifyDefaultParty(configuration);
}
-
+
public void setMetadata(Metadata metadata) {
+
this.metaData = metadata;
}
private RelyingParty findRelyingPartyByGroup(String providerIdFromTarget) {
if (metaData == null) { return null; }
-
+
EntityDescriptor provider = metaData.lookup(providerIdFromTarget);
if (provider != null) {
EntitiesDescriptor parent = provider.getEntitiesDescriptor();
private IdPConfig configuration;
private boolean overridenPassThruErrors = false;
private boolean passThruIsOverriden = false;
+ private boolean forceAttributePush = false;
+ private boolean forceAttributeNoPush = false;
public RelyingPartyImpl(Element partyConfig, IdPConfig globalConfig, Credentials credentials,
NameMapper nameMapper) throws ServiceProviderMapperException {
passThruIsOverriden = true;
}
+ // Determine whether or not we are forcing attribute push on or off
+ String forcePush = ((Element) partyConfig).getAttribute("forceAttributePush");
+ String forceNoPush = ((Element) partyConfig).getAttribute("forceAttributeNoPush");
+
+ if (forcePush != null && Boolean.valueOf(forcePush).booleanValue() && forceNoPush != null
+ && Boolean.valueOf(forceNoPush).booleanValue()) {
+ log.error("Invalid configuration: Attribute push is forced to ON and OFF for this relying "
+ + "party. Turning off forcing in favor of profile defaults.");
+ } else {
+ forceAttributePush = Boolean.valueOf(forcePush).booleanValue();
+ forceAttributeNoPush = Boolean.valueOf(forceNoPush).booleanValue();
+ log.debug("Attribute push forcing is set to (" + forceAttributePush + ").");
+ log.debug("No attribute push forcing is set to (" + forceAttributeNoPush + ").");
+ }
+
// Load and verify the name format that the HS should use in
// assertions for this RelyingParty
NodeList hsNameFormats = ((Element) partyConfig).getElementsByTagNameNS(IdPConfig.configNameSpace,
}
}
+ public boolean forceAttributePush() {
+
+ return forceAttributePush;
+ }
+
+ public boolean forceAttributeNoPush() {
+
+ return forceAttributeNoPush;
+ }
+
/**
* Default identity provider implementation.
*
return wrapped.passThruErrors();
}
+
+ public boolean forceAttributePush() {
+
+ return wrapped.forceAttributePush();
+ }
+
+ public boolean forceAttributeNoPush() {
+
+ return wrapped.forceAttributeNoPush();
+ }
}
/**
return wrapped.passThruErrors();
}
+
+ public boolean forceAttributePush() {
+
+ return false;
+ }
+
+ public boolean forceAttributeNoPush() {
+
+ return false;
+ }
}
/**
import edu.internet2.middleware.shibboleth.metadata.SPSSODescriptor;
/**
+ * <code>ProtocolHandler</code> implementation that responds to SSO flows as specified in "Shibboleth Architecture:
+ * Protocols and Profiles". Includes a compatibility mode for dealing with Shibboleth v1.1 SPs.
+ *
* @author Walter Hoehn
*/
public class ShibbolethV1SSOHandler extends BaseHandler implements IdPProtocolHandler {
// Package attributes for push, if necessary - don't attempt this for legacy providers (they don't support
// it)
- if (!relyingParty.isLegacyProvider() && pushAttributes(artifactProfile)) {
+ if (!relyingParty.isLegacyProvider() && pushAttributes(artifactProfile, relyingParty)) {
log.info("Resolving attributes for push.");
SAMLAssertion attrAssertion = generateAttributeAssertion(support, principal, relyingParty, authNSubject);
if (attrAssertion != null) {
rd.forward(req, res);
}
+ /**
+ * Boolean indication of which browser profile is in effect. "true" indicates Artifact and "false" indicates POST.
+ */
private static boolean useArtifactProfile(EntityDescriptor provider, String acceptanceURL) {
// TODO this logic needs to be updated
return false;
}
- private static boolean pushAttributes(boolean artifactProfile) {
+ /**
+ * Boolean indication of whether an assertion containing an attribute statement should be bundled in the response
+ * with the assertion containing the AuthN statement.
+ */
+ private static boolean pushAttributes(boolean artifactProfile, RelyingParty relyingParty) {
- if (artifactProfile) { return true; }
- // TODO implement overrides
- return false;
+ // By default push for Artifact and don't push for POST
+ // This can be overriden at the level of the relying party
+ if (relyingParty.forceAttributePush()) {
+ return true;
+ } else if (relyingParty.forceAttributeNoPush()) {
+ return false;
+ } else if (artifactProfile) {
+ return true;
+ } else {
+ return false;
+ }
}
+ /**
+ * Boolean indication of whethere or not a given assertion consumer URL is valid for a given SP.
+ */
private static boolean isValidAssertionConsumerURL(EntityDescriptor provider, String shireURL)
throws InvalidClientDataException {
<xs:attribute name="signingCredential" type="xs:string" use="optional"/>
<xs:attribute name="AAUrl" type="xs:anyURI" use="optional"/>
<xs:attribute name="passThruErrors" type="xs:boolean" use="optional"/>
+ <xs:attribute name="forceAttributePush" type="xs:boolean" use="optional"/>
+ <xs:attribute name="forceAttributeNoPush" type="xs:boolean" use="optional"/>
<xs:attribute name="defaultAuthMethod" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>