styleSheet="/shibboleth-sp/main.css"/>
<!-- Configure handling of outgoing messages and SOAP authentication. -->
- <DefaultRelyingParty authType="TLS" artifactEndpointIndex="1" signing="false" encryption="false">
+ <DefaultRelyingParty authType="TLS"
+ artifactEndpointIndex="1"
+ signing="false"
+ encryption="false"
+ requireConfidentiality="true"
+ requireTransportAuth="true"
+ signedAssertions="false"
+ chunkedEncoding="false"
+ connectTimeout="15" timeout="30"
+ >
<!-- Uncomment and modify to tweak settings for specific IdPs or groups. -->
<!-- <RelyingParty Name="SpecialFederation" keyName="SpecialKey"/> -->
</DefaultRelyingParty>
<!-- Each policy defines a set of rules to use to secure messages. -->
<SecurityPolicies>
<!-- The predefined policy enforces replay/freshness and permits signing and client TLS. -->
- <Policy id="default"
- validate="false"
- signedAssertions="false"
- requireConfidentiality="true"
- requireTransportAuth="true"
- chunkedEncoding="false"
- connectTimeout="15" timeout="30"
- >
+ <Policy id="default" validate="false">
<Rule type="MessageFlow" checkReplay="true" expires="60"/>
<Rule type="ClientCertAuth" errorFatal="true"/>
<Rule type="XMLSigning" errorFatal="true"/>
<attribute name="encryptionAlg" type="anyURI"/>\r
<attribute name="keyName" type="conf:string"/>\r
<attribute name="artifactEndpointIndex" type="unsignedShort"/>\r
+ <attribute name="chunkedEncoding" type="boolean"/>\r
+ <attribute name="connectTimeout" type="unsignedShort"/>\r
+ <attribute name="timeout" type="unsignedShort"/>\r
+ <attribute name="requireConfidentiality" type="boolean"/>\r
+ <attribute name="requireTransportAuth" type="boolean"/>\r
+ <attribute name="signedAssertions" type="boolean"/>\r
</attributeGroup>\r
\r
<element name="SecurityPolicies">\r
</sequence>\r
<attribute name="id" type="conf:string" use="required"/>\r
<attribute name="validate" type="boolean" default="false"/>\r
- <attribute name="signedAssertions" type="boolean" default="false"/>\r
- <attribute name="requireConfidentiality" type="boolean" default="true"/>\r
- <attribute name="requireTransportAuth" type="boolean" default="true"/>\r
- <attribute name="chunkedEncoding" type="boolean" default="true"/>\r
- <attribute name="connectTimeout" type="unsignedShort" default="15"/>\r
- <attribute name="timeout" type="unsignedShort" default="30"/>\r
<anyAttribute namespace="##any" processContents="lax"/>\r
</complexType>\r
</element>\r
shibsp::SecurityPolicy policy(application);
MetadataCredentialCriteria mcc(*AA);
shibsp::SOAPClient soaper(policy);
- const PropertySet* policySettings =
- application.getServiceProvider().getPolicySettings(application.getString("policyId").second);
- pair<bool,bool> signedAssertions = policySettings->getBool("signedAssertions");
auto_ptr_XMLCh binding(samlconstants::SAML1_BINDING_SOAP);
saml1p::Response* response=NULL;
auto_ptr<saml1p::Response> wrapper(response);
saml1::Assertion* newtoken = assertions.front();
+ pair<bool,bool> signedAssertions = application.getRelyingParty(ctx.getEntityDescriptor())->getBool("signedAssertions");
if (!newtoken->getSignature() && signedAssertions.first && signedAssertions.second) {
m_log.error("assertion unsigned, rejecting it based on signedAssertions policy");
return true;
shibsp::SecurityPolicy policy(application);
MetadataCredentialCriteria mcc(*AA);
shibsp::SOAPClient soaper(policy);
- const PropertySet* policySettings = application.getServiceProvider().getPolicySettings(application.getString("policyId").second);
- pair<bool,bool> signedAssertions = policySettings->getBool("signedAssertions");
const PropertySet* relyingParty = application.getRelyingParty(ctx.getEntityDescriptor());
+ pair<bool,bool> signedAssertions = relyingParty->getBool("signedAssertions");
pair<bool,const char*> encryption = relyingParty->getString("encryption");
auto_ptr_XMLCh binding(samlconstants::SAML20_BINDING_SOAP);
Category& log=Category::getInstance(SHIBSP_LOGCAT".SOAPClient");
log.debug("prepping SOAP transport for use by application (%s)", m_app.getId());
- pair<bool,bool> flag = m_settings->getBool("requireConfidentiality");
+ pair<bool,bool> flag = m_relyingParty->getBool("requireConfidentiality");
if ((!flag.first || flag.second) && !transport.isConfidential())
throw opensaml::BindingException("Transport confidentiality required, but not available.");
flag = m_settings->getBool("validate");
setValidating(flag.first && flag.second);
- flag = m_settings->getBool("requireTransportAuth");
+ flag = m_relyingParty->getBool("requireTransportAuth");
forceTransportAuthentication(!flag.first || flag.second);
opensaml::SOAPClient::prepareTransport(transport);
}
}
- transport.setConnectTimeout(m_settings->getUnsignedInt("connectTimeout").second);
- transport.setTimeout(m_settings->getUnsignedInt("timeout").second);
+ pair<bool,unsigned int> timeout = m_relyingParty->getUnsignedInt("connectTimeout");
+ transport.setConnectTimeout(timeout.first ? timeout.second : 10);
+ timeout = m_relyingParty->getUnsignedInt("timeout");
+ transport.setTimeout(timeout.first ? timeout.second : 20);
m_app.getServiceProvider().setTransportOptions(m_app.getString("policyId").second, transport);
HTTPSOAPTransport* http = dynamic_cast<HTTPSOAPTransport*>(&transport);
if (http) {
- flag = m_settings->getBool("chunkedEncoding");
- http->useChunkedEncoding(!flag.first || flag.second);
+ flag = m_relyingParty->getBool("chunkedEncoding");
+ http->useChunkedEncoding(flag.first && flag.second);
http->setRequestHeader("User-Agent", PACKAGE_NAME);
http->setRequestHeader(PACKAGE_NAME, PACKAGE_VERSION);
}
prop = application.getRelyingParty(NULL)->getString("signing");
if (prop.first && (!strcmp(prop.second,"true") || !strcmp(prop.second,"front")))
role->AuthnRequestsSigned(true);
- pair<bool,bool> flagprop =
- application.getServiceProvider().getPolicySettings(application.getString("policyId").second)->getBool("signedAssertions");
+ pair<bool,bool> flagprop = application.getRelyingParty(NULL)->getBool("signedAssertions");
if (flagprop.first && flagprop.second)
role->WantAssertionsSigned(true);
BrowserSSOProfileValidator ssoValidator(application.getAudiences(), now);
// With this flag on, we ignore any unsigned assertions.
- pair<bool,bool> flag = settings->getBool("signedAssertions");
+ const EntityDescriptor* entity = policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL;
+ pair<bool,bool> flag = application.getRelyingParty(entity)->getBool("signedAssertions");
// authnskew allows rejection of SSO if AuthnInstant is too old.
const PropertySet* sessionProps = application.getPropertySet("Sessions");
httpRequest,
httpResponse,
now + lifetime.second,
- policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL,
+ entity,
(!response->getMinorVersion().first || response->getMinorVersion().second==1) ?
samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM,
nameid.get(),
BrowserSSOProfileValidator ssoValidator(application.getAudiences(), now, dest.substr(0,dest.find('?')).c_str());
// With this flag on, we ignore any unsigned assertions.
- pair<bool,bool> flag = settings->getBool("signedAssertions");
+ const EntityDescriptor* entity = NULL;
+ pair<bool,bool> flag = make_pair(false,false);
+ if (alreadySecured && policy.getIssuerMetadata()) {
+ entity = dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent());
+ flag = application.getRelyingParty(entity)->getBool("signedAssertions");
+ }
// authnskew allows rejection of SSO if AuthnInstant is too old.
const PropertySet* sessionProps = application.getPropertySet("Sessions");
if (!alreadySecured && !policy.isAuthenticated())
throw SecurityPolicyException("Unable to establish security of incoming assertion.");
+ // If we hadn't established Issuer yet, redo the signedAssertions check.
+ if (!entity && policy.getIssuerMetadata()) {
+ entity = dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent());
+ flag = application.getRelyingParty(entity)->getBool("signedAssertions");
+ if (!(*a)->getSignature() && flag.first && flag.second)
+ throw SecurityPolicyException("The incoming assertion was unsigned, violating local security policy.");
+ }
+
// Now do profile and core semantic validation to ensure we can use it for SSO.
ssoValidator.validateAssertion(*(*a));
httpRequest,
httpResponse,
sessionExp,
- policy.getIssuerMetadata() ? dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent()) : NULL,
+ entity,
samlconstants::SAML20P_NS,
ssoName,
ssoStatement->getAuthnInstant() ? ssoStatement->getAuthnInstant()->getRawData() : NULL,