diff --git a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java index 7f38b81c..c73065b6 100644 --- a/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java +++ b/core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java @@ -249,8 +249,10 @@ public boolean isValid(String requestId) { } // Validate Conditions element exists - if (!this.checkOneCondition()) { - throw new ValidationError("The Assertion must include a Conditions element", ValidationError.MISSING_CONDITIONS); + if (settings.isWantConditionsPresent()) { + if (!this.checkOneCondition()) { + throw new ValidationError("The Assertion must include a Conditions element", ValidationError.MISSING_CONDITIONS); + } } // Validate Assertion timestamps diff --git a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java index f5c8565b..8a6e63fa 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java +++ b/core/src/main/java/com/onelogin/saml2/settings/Saml2Settings.java @@ -78,6 +78,7 @@ public class Saml2Settings { private boolean allowRepeatAttributeName = false; private boolean rejectDeprecatedAlg = false; private String uniqueIDPrefix = null; + private boolean wantConditionsPresent = true; // Compress private boolean compressRequest = true; @@ -1052,7 +1053,25 @@ public boolean getSPValidationOnly() { return this.spValidationOnly; } - + + + /** + * + * @return the wantConditionsPresentValue + */ + public boolean isWantConditionsPresent() { + return wantConditionsPresent; + } + + /** + * Set the wantConditionsPresent value, used to determine if the Conditions element is required + * + * @param wantConditionsPresent the wantConditionsPresent value + */ + public void setWantConditionsPresent(boolean wantConditionsPresent) { + this.wantConditionsPresent = wantConditionsPresent; + } + /** * Gets the SP metadata. The XML representation. * diff --git a/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java b/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java index ac1ef92f..c0eb9b4c 100644 --- a/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java +++ b/core/src/main/java/com/onelogin/saml2/settings/SettingsBuilder.java @@ -91,6 +91,7 @@ public class SettingsBuilder { public final static String SECURITY_WANT_MESSAGES_SIGNED = "onelogin.saml2.security.want_messages_signed"; public final static String SECURITY_WANT_ASSERTIONS_SIGNED = "onelogin.saml2.security.want_assertions_signed"; public final static String SECURITY_WANT_ASSERTIONS_ENCRYPTED = "onelogin.saml2.security.want_assertions_encrypted"; + public final static String SECURITY_WANT_CONDITIONS_PRESENT = "onelogin.saml2.security.want_conditions_present"; public final static String SECURITY_WANT_NAMEID = "onelogin.saml2.security.want_nameid"; public final static String SECURITY_WANT_NAMEID_ENCRYPTED = "onelogin.saml2.security.want_nameid_encrypted"; public final static String SECURITY_SIGN_METADATA = "onelogin.saml2.security.sign_metadata"; @@ -373,6 +374,10 @@ private void loadSecuritySetting() { if (wantXMLValidation != null) saml2Setting.setWantXMLValidation(wantXMLValidation); + Boolean wantConditionsPresent = loadBooleanProperty(SECURITY_WANT_CONDITIONS_PRESENT); + if (wantConditionsPresent != null) + saml2Setting.setWantConditionsPresent(wantConditionsPresent); + Boolean signMetadata = loadBooleanProperty(SECURITY_SIGN_METADATA); if (signMetadata != null) saml2Setting.setSignMetadata(signMetadata); diff --git a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java index cae24ce2..0562abd5 100644 --- a/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java +++ b/core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java @@ -1697,6 +1697,31 @@ public void testIsInValidConditions() throws IOException, Error, XPathExpression assertEquals("The Assertion must include a Conditions element", samlResponse.getError()); } + /** + * Tests the isValid method of SamlResponse + * Case: invalid Conditions + * + * @throws ValidationError + * @throws SettingsException + * @throws IOException + * @throws SAXException + * @throws ParserConfigurationException + * @throws XPathExpressionException + * @throws Error + * + * @see com.onelogin.saml2.authn.SamlResponse#isValid + */ + @Test + public void testIsInValidConditionsWithoutConditionsValidation() throws IOException, Error, XPathExpressionException, ParserConfigurationException, SAXException, SettingsException, ValidationError { + Saml2Settings settings = new SettingsBuilder().fromFile("config/config.mywithoutconditions.properties").build(); + String samlResponseEncoded = Util.getFileAsString("data/responses/invalids/no_conditions.xml.base64"); + setDateTime("2014-02-19T09:35:01Z"); + + SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest("https://example.com/newonelogin/demo1/index.php?acs", samlResponseEncoded)); + assertTrue(samlResponse.isValid()); + assertNull(samlResponse.getError()); + } + /** * Tests the isValid method of SamlResponse * Case: invalid Conditions diff --git a/core/src/test/resources/config/config.mywithoutconditions.properties b/core/src/test/resources/config/config.mywithoutconditions.properties new file mode 100644 index 00000000..f3a149d4 --- /dev/null +++ b/core/src/test/resources/config/config.mywithoutconditions.properties @@ -0,0 +1,145 @@ +# If 'strict' is True, then the Java Toolkit will reject unsigned +# or unencrypted messages if it expects them signed or encrypted +# Also will reject the messages if not strictly follow the SAML +onelogin.saml2.strict = true + +# Enable debug mode (to print errors) +onelogin.saml2.debug = true + +# Service Provider Data that we are deploying +# Identifier of the SP entity (must be a URI) +onelogin.saml2.sp.entityid = http://localhost:8080/java-saml-jspsample/metadata.jsp +# Specifies info about where and how the message MUST be +# returned to the requester, in this case our SP. +# URL Location where the from the IdP will be returned +onelogin.saml2.sp.assertion_consumer_service.url = http://localhost:8080/java-saml-jspsample/acs.jsp +# SAML protocol binding to be used when returning the or sending the +# message. Onelogin Toolkit supports for this endpoint the +# HTTP-POST binding only +onelogin.saml2.sp.assertion_consumer_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST + +# Specifies info about Logout service +# URL Location where the from the IdP will be returned or where to send the +onelogin.saml2.sp.single_logout_service.url = http://localhost:8080/java-saml-jspsample/sls.jsp + +# SAML protocol binding for the Single Logout Service of the SP. +# Onelogin Toolkit supports for this endpoint the HTTP-Redirect binding only +onelogin.saml2.sp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect + +# Specifies constraints on the name identifier to be used to +# represent the requested subject. +# Take a look on lib/Saml2/Constants.php to see the NameIdFormat supported +onelogin.saml2.sp.nameidformat = urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + +# Usually x509cert and privateKey of the SP are provided by files placed at +# the certs folder. But we can also provide them with the following parameters +onelogin.saml2.sp.x509cert = -----BEGIN CERTIFICATE-----MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo-----END CERTIFICATE----- + + +# Requires Format PKCS#8 BEGIN PRIVATE KEY +# If you have PKCS#1 BEGIN RSA PRIVATE KEY convert it by openssl pkcs8 -topk8 -inform pem -nocrypt -in sp.rsa_key -outform pem -out sp.pem +onelogin.saml2.sp.privatekey = -----BEGIN PRIVATE KEY-----MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOK9uFHs/nXrH9LcGorG6lB7Qs42iWK6mIE56wI7dIdsOuXf6r0ht+d+YTTis24xw+wjEHXrVN0Okh6wsKftzxo8chIo60+UB5NlKdvxAC7tpGNmrf49us/m5bdNx8IY+0pPK0c6B786UlujTvx1WFdDXh3UQPBclbWtFe5S3gLxAgMBAAECgYAPj9ngtZVZXoPWowinUbOvRmZ1ZMTVI91nsSPyCUacLM92C4I+7NuEZeYiDRUnkP7TbCyrCzXN3jwlIxdczzORhlXBBgg9Sw2fkV61CnDEMgw+aEeD5A0GDA6eTwkrawiOMs8vupjsi2/stPsa+bmpI6RnfdEKBdyDP6iQQhAxiQJBAPNtM7IMvRzlZBXoDaTTpP9rN2FR0ZcX0LT5aRZJ81qi+ZOBFeHUb6MyWvzZKfPinj9JO3s/9e3JbMXemRWBmvcCQQDuc+NfAeW200QyjoC3Ed3jueLMrY1Q3zTcSUhRPw/0pIKgRGZJerro8N6QY2JziV2mxK855gKTwwBigMHL2S9XAkEAwuBfjGDqXOG/uFHn6laNNvWshjqsIdus99Tbrj5RlfP2/YFP9VTOcsXzVYy9K0P3EA8ekVLpHQ4uCFJmF3OEjQJBAMvwO69/HOufhv1CWZ25XzAsRGhPqsRXEouw9XPfXpMavEm8FkuT9xXRJFkTVxl/i6RdJYx8Rwn/Rm34t0bUKqMCQQCrAtKCUn0PLcemAzPi8ADJlbMDG/IDXNbSej0Y4tw9Cdho1Q38XLZJi0RNdNvQJD1fWu3x9+QU/vJr7lMLzdoy-----END PRIVATE KEY----- + +# Identity Provider Data that we want connect with our SP +# Identifier of the IdP entity (must be a URI) +onelogin.saml2.idp.entityid = https://example.com/simplesaml/saml2/idp/metadata.php + +# SSO endpoint info of the IdP. (Authentication Request protocol) +# URL Target of the IdP where the SP will send the Authentication Request Message +onelogin.saml2.idp.single_sign_on_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SSOService.php + +# SAML protocol binding to be used when returning the +# message. Onelogin Toolkit supports for this endpoint the +# HTTP-Redirect binding only +onelogin.saml2.idp.single_sign_on_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect + +# SLO endpoint info of the IdP. +# URL Location of the IdP where the SP will send the SLO Request +onelogin.saml2.idp.single_logout_service.url = https://pitbulk.no-ip.org/simplesaml/saml2/idp/SingleLogoutService.php + +# SAML protocol binding to be used when returning the +# message. Onelogin Toolkit supports for this endpoint the +# HTTP-Redirect binding only +onelogin.saml2.idp.single_logout_service.binding = urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect + +# Public x509 certificate of the IdP +onelogin.saml2.idp.x509cert = -----BEGIN CERTIFICATE-----MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo-----END CERTIFICATE----- + +# Security settings +# + +# Indicates that the nameID of the sent by this SP +# will be encrypted. +onelogin.saml2.security.nameid_encrypted = true + +# Indicates whether the messages sent by this SP +# will be signed. [The Metadata of the SP will offer this info] +onelogin.saml2.security.authnrequest_signed = true + +# Indicates whether the messages sent by this SP +# will be signed. +onelogin.saml2.security.logoutrequest_signed = true + +# Indicates whether the messages sent by this SP +# will be signed. +onelogin.saml2.security.logoutresponse_signed = true + +# Indicates a requirement for the , and +# elements received by this SP to be signed. +onelogin.saml2.security.want_messages_signed = false + +# Indicates a requirement for the of the to be signed +onelogin.saml2.security.want_assertions_signed = true + +# Indicates a requirement for the Metadata of this SP to be signed. +# Right now supported null/false (in order to not sign) or true (sign using SP private key) +onelogin.saml2.security.sign_metadata = true + +# Indicates a requirement for the Assertions received by this SP to be encrypted +onelogin.saml2.security.want_assertions_encrypted = false + +# Indicates a requirement for the NameID received by this SP to be encrypted +onelogin.saml2.security.want_nameid = true + +# Indicates a requirement for the NameID received by this SP to be encrypted +onelogin.saml2.security.want_nameid_encrypted = false + +# Authentication context. +# Set Empty and no AuthContext will be sent in the AuthNRequest, +# Set comma separated values urn:oasis:names:tc:SAML:2.0:ac:classes:urn:oasis:names:tc:SAML:2.0:ac:classes:Password +onelogin.saml2.security.requested_authncontext = urn:oasis:names:tc:SAML:2.0:ac:classes:urn:oasis:names:tc:SAML:2.0:ac:classes:Password + +# Allows the authn comparison parameter to be set, defaults to 'exact' +onelogin.saml2.security.requested_authncontextcomparison = exact + +onelogin.saml2.security.want_conditions_present = false + + +# Indicates if the SP will validate all received xmls. +# (In order to validate the xml, 'strict' and 'wantXMLValidation' must be true). +onelogin.saml2.security.want_xml_validation = true + +# Algorithm that the toolkit will use on signing process. Options: +# 'http://www.w3.org/2000/09/xmldsig#rsa-sha1' +# 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' +# 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384' +# 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512' +onelogin.saml2.security.signature_algorithm = http://www.w3.org/2001/04/xmldsig-more#rsa-sha512 + +# Algorithm that the toolkit will use on digest process. Options: +# 'http://www.w3.org/2000/09/xmldsig#sha1' +# 'http://www.w3.org/2001/04/xmlenc#sha256' +# 'http://www.w3.org/2001/04/xmldsig-more#sha384' +# 'http://www.w3.org/2001/04/xmlenc#sha512' +onelogin.saml2.security.digest_algorithm = http://www.w3.org/2001/04/xmlenc#sha512 + +# Organization +onelogin.saml2.organization.name = SP Java +onelogin.saml2.organization.displayname = SP Java Example +onelogin.saml2.organization.url = http://sp.example.com + +# Contacts +onelogin.saml2.contacts.technical.given_name = Technical Guy +onelogin.saml2.contacts.technical.email_address = technical@example.com +onelogin.saml2.contacts.support.given_name = Support Guy +onelogin.saml2.contacts.support.email_address = support@example.com \ No newline at end of file