package com.onelogin.saml2.test.logout;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.xml.xpath.XPathExpressionException;
import java.security.PrivateKey;
import org.w3c.dom.Document;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import com.onelogin.saml2.logout.LogoutRequest;
import com.onelogin.saml2.http.HttpRequest;
import com.onelogin.saml2.exception.XMLEntityException;
import com.onelogin.saml2.exception.Error;
import com.onelogin.saml2.exception.SettingsException;
import com.onelogin.saml2.exception.ValidationError;
import com.onelogin.saml2.settings.Saml2Settings;
import com.onelogin.saml2.settings.SettingsBuilder;
import com.onelogin.saml2.test.NaiveUrlEncoder;
import com.onelogin.saml2.util.Constants;
import com.onelogin.saml2.util.Util;
public class LogoutRequestTest {
@Rule
public ExpectedException expectedEx = ExpectedException.none();
/**
* Tests the constructor and the getEncodedLogoutRequest method of LogoutRequest
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getEncodedLogoutRequest
*/
@Test
public void testGetEncodedLogoutRequestSimulated() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
final String logoutRequestString = Util.getFileAsString("data/logout_requests/logout_request.xml");
LogoutRequest logoutRequest = new LogoutRequest(settings) {
@Override
public String getLogoutRequestXml() {
return logoutRequestString;
}
};
String expectedLogoutRequestStringBase64Deflated = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
String expectedLogoutRequestStringBase64 = Util.getFileAsString("data/logout_requests/logout_request.xml.base64");
String logoutRequestStringBase64Deflated = logoutRequest.getEncodedLogoutRequest();
assertEquals(logoutRequestStringBase64Deflated, expectedLogoutRequestStringBase64Deflated);
logoutRequestStringBase64Deflated = logoutRequest.getEncodedLogoutRequest(null);
assertEquals(logoutRequestStringBase64Deflated, expectedLogoutRequestStringBase64Deflated);
logoutRequestStringBase64Deflated = logoutRequest.getEncodedLogoutRequest(true);
assertEquals(logoutRequestStringBase64Deflated, expectedLogoutRequestStringBase64Deflated);
logoutRequestStringBase64Deflated = logoutRequest.getEncodedLogoutRequest(false);
assertNotEquals(logoutRequestStringBase64Deflated, expectedLogoutRequestStringBase64Deflated);
assertEquals(logoutRequestStringBase64Deflated,expectedLogoutRequestStringBase64);
settings.setCompressRequest(true);
logoutRequest = new LogoutRequest(settings) {
@Override
public String getLogoutRequestXml() {
return logoutRequestString;
}
};
logoutRequestStringBase64Deflated = logoutRequest.getEncodedLogoutRequest(null);
assertEquals(logoutRequestStringBase64Deflated, expectedLogoutRequestStringBase64Deflated);
settings.setCompressRequest(false);
logoutRequest = new LogoutRequest(settings) {
@Override
public String getLogoutRequestXml() {
return logoutRequestString;
}
};
logoutRequestStringBase64Deflated = logoutRequest.getEncodedLogoutRequest(null);
assertNotEquals(logoutRequestStringBase64Deflated, expectedLogoutRequestStringBase64Deflated);
assertEquals(logoutRequestStringBase64Deflated, expectedLogoutRequestStringBase64);
}
/**
* Tests the constructor and the getEncodedAuthnRequest method of LogoutRequest
* Case: Only settings
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest
*/
@Test
public void testConstructor() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
LogoutRequest logoutRequest = new LogoutRequest(settings);
String logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
assertThat(logoutRequestStr, containsString("ID=\"" + logoutRequest.getId() + "\""));
assertThat(logoutRequestStr, not(containsString("<samlp:SessionIndex>")));
}
/**
* Tests the constructor and the getEncodedAuthnRequest method of LogoutRequest
* Case: settings + request
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest
*/
@Test
public void testConstructorWithRequest() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
final String requestURL = "/";
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
LogoutRequest logoutRequest = new LogoutRequest(settings, newHttpRequest(requestURL, samlRequestEncoded));
String logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
}
/**
* Tests the constructor and the getEncodedAuthnRequest method of LogoutRequest
* Case: session index
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest
*/
@Test
public void testConstructorWithSessionIndex() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String sessionIndex = "_51be37965feb5579d803141076936dc2e9d1d98ebf";
LogoutRequest logoutRequest = new LogoutRequest(settings, null, null, sessionIndex);
String logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
String expectedSessionIndex = "<samlp:SessionIndex>_51be37965feb5579d803141076936dc2e9d1d98ebf</samlp:SessionIndex>";
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
assertThat(logoutRequestStr, containsString(expectedSessionIndex));
logoutRequest = new LogoutRequest(settings, null, null, null);
logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
assertThat(logoutRequestStr, not(containsString("<samlp:SessionIndex>")));
}
/**
* Tests the constructor and the getEncodedAuthnRequest method of LogoutRequest
* Case: encrypted NameId
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest
*/
@Test
public void testConstructorWithEncryptedNameID() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.all.properties").build();
LogoutRequest logoutRequest = new LogoutRequest(settings);
String logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, containsString("<saml:EncryptedID><xenc:EncryptedData"));
settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
logoutRequest = new LogoutRequest(settings);
logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, not(containsString("<saml:EncryptedID><xenc:EncryptedData")));
}
/**
* Tests the getLogoutRequestXml method of LogoutRequest
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getLogoutRequestXml
*/
@Test
public void testGetLogoutRequestXml() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
LogoutRequest logoutRequest = new LogoutRequest(settings);
String logoutRequestXML = logoutRequest.getLogoutRequestXml();
assertThat(logoutRequestXML, containsString("<samlp:LogoutRequest"));
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request.xml.base64");
String requestURL = "/";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
logoutRequest = new LogoutRequest(settings, httpRequest);
logoutRequestXML = logoutRequest.getLogoutRequestXml();
assertThat(logoutRequestXML, containsString("<samlp:LogoutRequest"));
}
/**
* Tests the getNameIdData method of LogoutRequest
* Case: Able to get the NameIdData
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getNameIdData
*/
@Test
public void testGetNameIdData() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
LogoutRequest logoutRequest = new LogoutRequest(settings, null, "ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c", null);
String logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
String nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, null).toString();
assertThat(nameIdDataStr, containsString("Format=urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"));
assertThat(nameIdDataStr, containsString("Value=ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c"));
assertThat(nameIdDataStr, not(containsString("SPNameQualifier")));
logoutRequest = new LogoutRequest(settings, null, null, null);
logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, null).toString();
assertThat(nameIdDataStr, containsString("Format=urn:oasis:names:tc:SAML:2.0:nameid-format:entity"));
assertThat(nameIdDataStr, containsString("Value=http://idp.example.com/"));
assertThat(nameIdDataStr, containsString("SPNameQualifier=http://localhost:8080/java-saml-jspsample/metadata.jsp"));
// This settings file contains as IdP cert the SP cert, so I can use the getSPkey to decrypt.
settings = new SettingsBuilder().fromFile("config/config.samecerts.properties").build();
logoutRequest = new LogoutRequest(settings, null, "ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c", null);
logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
PrivateKey key = settings.getSPkey();
nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, key).toString();
assertThat(nameIdDataStr, containsString("Format=urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"));
assertThat(nameIdDataStr, containsString("Value=ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c"));
assertThat(nameIdDataStr, not(containsString("SPNameQualifier")));
logoutRequest = new LogoutRequest(settings, null, "ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c", null, "urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress");
logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, key).toString();
assertThat(nameIdDataStr, containsString("urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress"));
assertThat(nameIdDataStr, containsString("Value=ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c"));
assertThat(nameIdDataStr, not(containsString("SPNameQualifier")));
String keyString = Util.getFileAsString("data/customPath/certs/sp.pem");
key = Util.loadPrivateKey(keyString);
logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request_encrypted_nameid.xml");
nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, key).toString();
assertThat(nameIdDataStr, containsString("Format=urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress"));
assertThat(nameIdDataStr, containsString("Value=ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69"));
assertThat(nameIdDataStr, containsString("SPNameQualifier=https://pitbulk.no-ip.org/newonelogin/demo1/metadata.php"));
}
/**
* Tests the getId method of LogoutRequest
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getId
*/
@Test
public void testGetId() throws Exception {
String samlRequest = Util.getFileAsString("data/logout_requests/logout_request.xml");
String id = LogoutRequest.getId(samlRequest);
String expectedId = "ONELOGIN_21584ccdfaca36a145ae990442dcd96bfe60151e";
assertEquals(expectedId, id);
Document samlRequestDoc = Util.loadXML(samlRequest);
id = LogoutRequest.getId(samlRequestDoc);
assertEquals(expectedId, id);
assertNull(LogoutRequest.getId(""));
}
/**
* Tests the getNameIdData method of LogoutRequest
* Case: Not able to get the NameIdData due no private key to decrypt
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getNameIdData
*/
@Test
public void testGetNameIdDataNoKey() throws Exception {
expectedEx.expect(SettingsException.class);
expectedEx.expectMessage("Key is required in order to decrypt the NameID");
String logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request_encrypted_nameid.xml");
String nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, null).toString();
}
/**
* Tests the getNameIdData method of LogoutRequest
* Case: Not able to get the NameIdData due wrong private key to decrypt.
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getNameIdData
*/
@Test
public void testGetNameIdDataWrongKey() throws Exception {
expectedEx.expect(Exception.class);
expectedEx.expectMessage("algid parse error, not a sequence");
String logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request_encrypted_nameid.xml");
String keyString = Util.getFileAsString("data/misc/sp3.key");
PrivateKey key = Util.loadPrivateKey(keyString);
String nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, key).toString();
}
/**
* Tests the getNameIdData method of LogoutRequest
* Case: Not NameId element.
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getNameIdData
*/
@Test
public void testGetNameIdDataNoNameId() throws Exception {
expectedEx.expect(ValidationError.class);
expectedEx.expectMessage("No name id found in Logout Request.");
String logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request_no_nameid.xml");
String nameIdDataStr = LogoutRequest.getNameIdData(logoutRequestStr, null).toString();
}
/**
* Tests the getNameId method of LogoutRequest
* Case: Able to get the NameID
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getNameId
*/
@Test
public void testGetNameId() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
LogoutRequest logoutRequest = new LogoutRequest(settings, null, "ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c", null);
String logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
String logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
String expectedNameIdStr = "ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c";
String nameIdStr = LogoutRequest.getNameId(logoutRequestStr, null).toString();
assertEquals(expectedNameIdStr, nameIdStr);
logoutRequest = new LogoutRequest(settings, null, null, null);
logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
assertThat(logoutRequestStr, containsString("<samlp:LogoutRequest"));
expectedNameIdStr = "http://idp.example.com/";
nameIdStr = LogoutRequest.getNameId(logoutRequestStr, null).toString();
assertEquals(expectedNameIdStr, nameIdStr);
nameIdStr = LogoutRequest.getNameId(logoutRequestStr).toString();
assertEquals(expectedNameIdStr, nameIdStr);
Document logoutRequestDoc = Util.loadXML(logoutRequestStr);
nameIdStr = LogoutRequest.getNameId(logoutRequestDoc).toString();
assertEquals(expectedNameIdStr, nameIdStr);
// This settings file contains as IdP cert the SP cert, so I can use the getSPkey to decrypt.
settings = new SettingsBuilder().fromFile("config/config.samecerts.properties").build();
logoutRequest = new LogoutRequest(settings, null, "ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c", null);
logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
PrivateKey key = settings.getSPkey();
nameIdStr = LogoutRequest.getNameId(logoutRequestStr, key).toString();
expectedNameIdStr = "ONELOGIN_1e442c129e1f822c8096086a1103c5ee2c7cae1c";
assertEquals(expectedNameIdStr, nameIdStr);
String keyString = Util.getFileAsString("data/customPath/certs/sp.pem");
key = Util.loadPrivateKey(keyString);
logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request_encrypted_nameid.xml");
nameIdStr = LogoutRequest.getNameId(logoutRequestStr, key).toString();
expectedNameIdStr = "ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69";
assertEquals(expectedNameIdStr, nameIdStr);
logoutRequestDoc = Util.loadXML(logoutRequestStr);
nameIdStr = LogoutRequest.getNameId(logoutRequestDoc, key).toString();
assertEquals(expectedNameIdStr, nameIdStr);
}
/**
* Tests the getNameId method of LogoutRequest
* Case: Not able to get the NameID due no private key to decrypt
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getNameId
*/
@Test
public void testGetNameIdNoKey() throws Exception {
expectedEx.expect(SettingsException.class);
expectedEx.expectMessage("Key is required in order to decrypt the NameID");
String logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request_encrypted_nameid.xml");
String nameIdStr = LogoutRequest.getNameId(logoutRequestStr, null).toString();
}
/**
* Tests the getNameId method of LogoutRequest
* Case: Not able to get the NameID due wrong private key to decrypt.
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getNameId
*/
@Test
public void testGetNameIdWrongKey() throws Exception {
expectedEx.expect(Exception.class);
expectedEx.expectMessage("algid parse error, not a sequence");
String logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request_encrypted_nameid.xml");
String keyString = Util.getFileAsString("data/misc/sp3.key");
PrivateKey key = Util.loadPrivateKey(keyString);
String nameIdStr = LogoutRequest.getNameIdData(logoutRequestStr, key).toString();
}
/**
* Tests the getIssuer method of LogoutRequest
*
* @throws IOException
* @throws URISyntaxException
* @throws XPathExpressionException
*
* @see com.onelogin.saml2.logout.LogoutRequest#getIssuer
*/
@Test
public void testGetIssuer() throws URISyntaxException, IOException, XPathExpressionException {
String logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request.xml");
String expectedIssuer = "http://idp.example.com/";
String issuer = LogoutRequest.getIssuer(logoutRequestStr);
assertEquals(expectedIssuer, issuer);
logoutRequestStr = logoutRequestStr.replace("<saml:Issuer>http://idp.example.com/</saml:Issuer>", "");
issuer = LogoutRequest.getIssuer(logoutRequestStr);
assertNull(issuer);
}
/**
* Tests the getSessionIndexes method of LogoutRequest
*
* @throws IOException
* @throws URISyntaxException
* @throws XPathExpressionException
* @throws XMLEntityException
* @throws Error
*
* @see com.onelogin.saml2.logout.LogoutRequest#getSessionIndexes
*/
@Test
public void testGetSessionIndexes() throws URISyntaxException, IOException, XPathExpressionException, XMLEntityException, Error {
String logoutRequestStr = Util.getFileAsString("data/logout_requests/logout_request.xml");
List<String> expectedIndexes = new ArrayList<String>();
List <String> indexes = LogoutRequest.getSessionIndexes(logoutRequestStr);
assertEquals(expectedIndexes, indexes);
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String sessionIndex = "_51be37965feb5579d803141076936dc2e9d1d98ebf";
expectedIndexes.add(sessionIndex);
LogoutRequest logoutRequest = new LogoutRequest(settings, null, null, sessionIndex);
String logoutRequestStringBase64 = logoutRequest.getEncodedLogoutRequest();
logoutRequestStr = Util.base64decodedInflated(logoutRequestStringBase64);
indexes = LogoutRequest.getSessionIndexes(logoutRequestStr);
assertEquals(expectedIndexes, indexes);
}
/**
* Tests the isValid method of LogoutRequest
* Case: Invalid Issuer
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsInvalidIssuer() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/invalids/invalid_issuer.xml.base64");
final String requestURL = "http://stuff.com/endpoints/endpoints/sls.php";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
settings.setStrict(false);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(true);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("Invalid issuer in the Logout Request. Was 'https://example.hello.com/access/saml', but expected 'http://idp.example.com/'", logoutRequest.getError());
}
/**
* Tests the isValid method of LogoutRequest
* Case: Invalid XML
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsInValidWrongXML() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/invalids/invalid_xml.xml.base64");
final String requestURL = "http://stuff.com/endpoints/endpoints/sls.php";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
settings.setWantXMLValidation(true);
settings.setStrict(false);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(true);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd", logoutRequest.getError());
settings.setWantXMLValidation(false);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(false);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
}
/**
* Tests the isValid method of LogoutRequest
* Case: Invalid Destination
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsInvalidDestination() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
final String requestURL = "/";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
settings.setStrict(false);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(true);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertThat(logoutRequest.getError(), containsString("The LogoutRequest was received at"));
}
/**
* Tests the isValid method of LogoutRequest
* Case: Invalid NotOnOrAfter
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsInvalidNotOnOrAfter() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/invalids/not_after_failed.xml.base64");
final String requestURL = "http://stuff.com/endpoints/endpoints/sls.php";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
settings.setStrict(false);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(true);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("Could not validate timestamp: expired. Check system clock.", logoutRequest.getError());
}
/**
* Tests the isValid method of LogoutRequest
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsValid() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
String requestURL = "/";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
settings.setStrict(true);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
settings.setStrict(false);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
requestURL = "http://stuff.com/endpoints/endpoints/sls.php";
httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
settings.setStrict(true);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(false);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
}
@Test
public void testIsInValidSign_defaultUrlEncode() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.knownIdpPrivateKey.properties").build();
settings.setStrict(true);
settings.setWantMessagesSigned(true);
final String requestURL = "https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls";
String samlRequestEncoded = "lVLBitswEP0Vo7tjeWzJtki8LIRCYLvbNksPewmyPc6K2pJqyXQ/v1LSQlroQi/DMJr33rwZbZ2cJysezNms/gt+X9H55G2etBOXlx1ZFy2MdMoJLWd0wvfieP/xQcCGCrsYb3ozkRvI+wjpHC5eGU2Sw35HTg3lA8hqZFwWFcMKsStpxbEsxoLXeQN9OdY1VAgk+YqLC8gdCUQB7tyKB+281D6UaF6mtEiBPudcABcMXkiyD26Ulv6CevXeOpFlVvlunb5ttEmV3ZjlnGn8YTRO5qx0NuBs8kzpAd829tXeucmR5NH4J/203I8el6gFRUqbFPJnyEV51Wq30by4TLW0/9ZyarYTxt4sBsjUYLMZvRykl1Fxm90SXVkfwx4P++T4KSafVzmpUcVJ/sfSrQZJPphllv79W8WKGtLx0ir8IrVTqD1pT2MH3QAMSs4KTvui71jeFFiwirOmprwPkYW063+5uRq4urHiiC4e8hCX3J5wqAEGaPpw9XB5JmkBdeDqSlkz6CmUXdl0Qae5kv2F/1384wu3PwE=";
String relayState = "_1037fbc88ec82ce8e770b2bed1119747bb812a07e6";
String sigAlg = Constants.SHA256;
String queryString = "SAMLRequest=" + Util.urlEncoder(samlRequestEncoded);
queryString += "&RelayState=" + Util.urlEncoder(relayState);
queryString += "&SigAlg=" + Util.urlEncoder(sigAlg);
//This signature is based on the query string above
String signature = "cxDTcLRHhXJKGYcjZE2RRz5p7tVg/irNimq48KkJ0n10wiGwAmuzUByxEm4OHbetDrHGtxI5ygjrR0/HcrD8IkYyI5Ie4r5tJYkfdtpUrvOQ7khbBvP9GzEbZIrz7eH1ALdCDchORaRB/cs6v+OZbBj5uPTrN//wOhZl2k9H2xVW/SYy17jDoIKh/wvqtQ9FF+h2UxdUEhxeB/UUXOC6nVLMo+RGaamSviYkUE1Zu1tmalO+F6FivNQ31T/TkqzWz0KEjmnFs3eKbHakPVuUHpDQm7Gf2gBS1TXwVQsL7e2axtvv4RH5djlq1Z2WH2V+PwGOkIvLxf3igGUSR1A8bw==";
HttpRequest httpRequest = new HttpRequest(requestURL, queryString)
.addParameter("SAMLRequest", samlRequestEncoded)
.addParameter("RelayState", relayState)
.addParameter("SigAlg", sigAlg)
.addParameter("Signature", signature);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue("Signature validation failed", logoutRequest.isValid());
}
@Test
public void testIsInValidSign_naiveUrlEncoding() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.knownIdpPrivateKey.properties").build();
settings.setStrict(true);
settings.setWantMessagesSigned(true);
final String requestURL = "https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls";
String samlRequestEncoded = "lVLBitswEP0Vo7tjeWzJtki8LIRCYLvbNksPewmyPc6K2pJqyXQ/v1LSQlroQi/DMJr33rwZbZ2cJysezNms/gt+X9H55G2etBOXlx1ZFy2MdMoJLWd0wvfieP/xQcCGCrsYb3ozkRvI+wjpHC5eGU2Sw35HTg3lA8hqZFwWFcMKsStpxbEsxoLXeQN9OdY1VAgk+YqLC8gdCUQB7tyKB+281D6UaF6mtEiBPudcABcMXkiyD26Ulv6CevXeOpFlVvlunb5ttEmV3ZjlnGn8YTRO5qx0NuBs8kzpAd829tXeucmR5NH4J/203I8el6gFRUqbFPJnyEV51Wq30by4TLW0/9ZyarYTxt4sBsjUYLMZvRykl1Fxm90SXVkfwx4P++T4KSafVzmpUcVJ/sfSrQZJPphllv79W8WKGtLx0ir8IrVTqD1pT2MH3QAMSs4KTvui71jeFFiwirOmprwPkYW063+5uRq4urHiiC4e8hCX3J5wqAEGaPpw9XB5JmkBdeDqSlkz6CmUXdl0Qae5kv2F/1384wu3PwE=";
String relayState = "_1037fbc88ec82ce8e770b2bed1119747bb812a07e6";
String sigAlg = Constants.SHA256;
String queryString = "SAMLRequest=" + NaiveUrlEncoder.encode(samlRequestEncoded);
queryString += "&RelayState=" + NaiveUrlEncoder.encode(relayState);
queryString += "&SigAlg=" + NaiveUrlEncoder.encode(sigAlg);
//This signature is based on the query string above
String signatureNaiveEncoding = "Gj2mUq6RBPAPXI9VjDDlwAxueSEBlOfgpWKLpsQbqIp+2XPFtC/vPAZpuPjHCDNNnAI3WKZa4l8ijwQBTqQwKz88k9gTx6vcLxPl2L4SrWdLOokiGrIVYJ+0sK2hapHHMa7WzGiTgpeTuejHbD4ptneaRXl4nrJAEo0WJ/rNTSWbJpnb+ENtgBnsfkmj+6z1KFY70ruo7W/vme21Jg+4XNfBSGl6LLSjEnZHJG0ET80HKvJEZayv4BQGZ3MShcSMyab/w+rLfDvDRA5RcRxw+NHOXo/kxZ3qhpa6daOwG69+PiiWmusmB2gaSq6jy2L55zFks9a36Pt5l5fYA2dE4g==";
HttpRequest httpRequest = new HttpRequest(requestURL, queryString)
.addParameter("SAMLRequest", samlRequestEncoded)
.addParameter("RelayState", relayState)
.addParameter("SigAlg", sigAlg)
.addParameter("Signature", signatureNaiveEncoding);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue("Signature validation failed", logoutRequest.isValid());
}
/**
* Tests the isValid method of LogoutRequest
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsInValidSign() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.my.properties").build();
settings.setStrict(false);
settings.setWantMessagesSigned(true);
final String requestURL = "https://pitbulk.no-ip.org/newonelogin/demo1/index.php?sls";
String samlRequestEncoded = "lVLBitswEP0Vo7tjeWzJtki8LIRCYLvbNksPewmyPc6K2pJqyXQ/v1LSQlroQi/DMJr33rwZbZ2cJysezNms/gt+X9H55G2etBOXlx1ZFy2MdMoJLWd0wvfieP/xQcCGCrsYb3ozkRvI+wjpHC5eGU2Sw35HTg3lA8hqZFwWFcMKsStpxbEsxoLXeQN9OdY1VAgk+YqLC8gdCUQB7tyKB+281D6UaF6mtEiBPudcABcMXkiyD26Ulv6CevXeOpFlVvlunb5ttEmV3ZjlnGn8YTRO5qx0NuBs8kzpAd829tXeucmR5NH4J/203I8el6gFRUqbFPJnyEV51Wq30by4TLW0/9ZyarYTxt4sBsjUYLMZvRykl1Fxm90SXVkfwx4P++T4KSafVzmpUcVJ/sfSrQZJPphllv79W8WKGtLx0ir8IrVTqD1pT2MH3QAMSs4KTvui71jeFFiwirOmprwPkYW063+5uRq4urHiiC4e8hCX3J5wqAEGaPpw9XB5JmkBdeDqSlkz6CmUXdl0Qae5kv2F/1384wu3PwE=";
String relayState = "_1037fbc88ec82ce8e770b2bed1119747bb812a07e6";
String sigAlg = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
String signature = "XCwCyI5cs7WhiJlB5ktSlWxSBxv+6q2xT3c8L7dLV6NQG9LHWhN7gf8qNsahSXfCzA0Ey9dp5BQ0EdRvAk2DIzKmJY6e3hvAIEp1zglHNjzkgcQmZCcrkK9Czi2Y1WkjOwR/WgUTUWsGJAVqVvlRZuS3zk3nxMrLH6f7toyvuJc=";
HttpRequest httpRequest = new HttpRequest(requestURL)
.addParameter("SAMLRequest", samlRequestEncoded)
.addParameter("RelayState", relayState)
.addParameter("SigAlg", sigAlg)
.addParameter("Signature", signature);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(true);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(false);
String signature2 = "vfWbbc47PkP3ejx4bjKsRX7lo9Ml1WRoE5J5owF/0mnyKHfSY6XbhO1wwjBV5vWdrUVX+xp6slHyAf4YoAsXFS0qhan6txDiZY4Oec6yE+l10iZbzvie06I4GPak4QrQ4gAyXOSzwCrRmJu4gnpeUxZ6IqKtdrKfAYRAcVf3333=";
httpRequest = httpRequest.removeParameter("Signature")
.addParameter("Signature", signature2);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("Signature validation failed. Logout Request rejected", logoutRequest.getError());
httpRequest = httpRequest.removeParameter("Signature")
.addParameter("Signature", signature)
.removeParameter("SigAlg");
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
httpRequest = httpRequest.removeParameter("Signature");
logoutRequest = new LogoutRequest(settings, httpRequest);
assertTrue(logoutRequest.isValid());
settings.setStrict(true);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("The Message of the Logout Request is not signed and the SP requires it", logoutRequest.getError());
httpRequest = httpRequest.addParameter("Signature", signature);
settings = new SettingsBuilder().fromFile("config/config.mywithnocert.properties").build();
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("In order to validate the sign on the Logout Request, the x509cert of the IdP is required", logoutRequest.getError());
}
/**
* Tests the isValid method of LogoutRequest
* Case: No SAML Logout Request
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsValidNoLogoutRequest() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String samlRequestEncoded = "";
final String requestURL = "/";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("SAML Logout Request is not loaded", logoutRequest.getError());
}
/**
* Tests the isValid method of LogoutRequest
* Case: No current URL
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#isValid
*/
@Test
public void testIsValidNoCurrentURL() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
LogoutRequest logoutRequest = new LogoutRequest(settings, null);
assertFalse(logoutRequest.isValid());
assertEquals("The HttpRequest of the current host was not established", logoutRequest.getError());
final String requestURL = "";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertFalse(logoutRequest.isValid());
assertEquals("The URL of the current host was not established", logoutRequest.getError());
}
/**
* Tests the getError method of LogoutRequest
*
* @throws Exception
*
* @see com.onelogin.saml2.logout.LogoutRequest#getError
*/
@Test
public void testGetError() throws Exception {
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
settings.setStrict(true);
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
final String requestURL = "/";
HttpRequest httpRequest = newHttpRequest(requestURL, samlRequestEncoded);
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertNull(logoutRequest.getError());
logoutRequest.isValid();
assertThat(logoutRequest.getError(), containsString("The LogoutRequest was received at"));
settings.setStrict(false);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertNull(logoutRequest.getError());
logoutRequest.isValid();
assertNull(logoutRequest.getError());
}
private static HttpRequest newHttpRequest(String requestURL, String samlRequestEncoded) {
return new HttpRequest(requestURL).addParameter("SAMLRequest", samlRequestEncoded);
}
}