Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class SamlResponse {
/**
* After validation, if it fails this property has the cause of the problem
*/
private String error;
private Exception validationException;

/**
* Constructor to have a Response object fully built and ready to validate the saml response.
Expand Down Expand Up @@ -148,7 +148,7 @@ public void loadXmlFromBase64(String responseStr) throws ParserConfigurationExce
* @return if the response is valid or not
*/
public boolean isValid(String requestId) {
error = null;
validationException = null;

try {
if (samlResponseDocument == null) {
Expand Down Expand Up @@ -311,9 +311,9 @@ public boolean isValid(String requestId) {
LOGGER.debug("SAMLResponse validated --> {}", samlResponseString);
return true;
} catch (Exception e) {
error = e.getMessage();
validationException = e;
LOGGER.debug("SAMLResponse invalid --> {}", samlResponseString);
LOGGER.error(error);
LOGGER.error(validationException.getMessage());
return false;
}
}
Expand Down Expand Up @@ -964,15 +964,24 @@ public void setDestinationUrl(String url) {
/**
* After execute a validation process, if fails this method returns the cause
*
* @return the cause of the validation error
* @return the cause of the validation error as a string
*/
public String getError() {
if (error != null) {
return error;
if (validationException != null) {
return validationException.getMessage();
}
return null;
}

/**
* After execute a validation process, if fails this method returns the Exception object
*
* @return the cause of the validation error
*/
public Exception getValidationException() {
return validationException;
}

/**
* Extracts a node from the DOMDocument (Assertion).
*
Expand Down
23 changes: 18 additions & 5 deletions core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public class LogoutRequest {
/**
* After validation, if it fails this property has the cause of the problem
*/
private String error;
private Exception validationException;

/**
* Constructs the LogoutRequest object.
Expand Down Expand Up @@ -366,7 +366,7 @@ private static StringBuilder getLogoutRequestTemplate() {
* @throws Exception
*/
public Boolean isValid() throws Exception {
error = null;
validationException = null;

try {
if (this.logoutRequestString == null || logoutRequestString.isEmpty()) {
Expand Down Expand Up @@ -474,9 +474,9 @@ public Boolean isValid() throws Exception {
LOGGER.debug("LogoutRequest validated --> " + logoutRequestString);
return true;
} catch (Exception e) {
error = e.getMessage();
validationException = e;
LOGGER.debug("LogoutRequest invalid --> " + logoutRequestString);
LOGGER.error(error);
LOGGER.error(validationException.getMessage());
return false;
}
}
Expand Down Expand Up @@ -737,9 +737,22 @@ public static List<String> getSessionIndexes(String samlLogoutRequestString) thr
* @return the cause of the validation error
*/
public String getError() {
return error;
if (validationException != null) {
return validationException.getMessage();
}
return null;
}

/**
* After execute a validation process, if fails this method returns the Exception object
*
* @return the cause of the validation error
*/
public Exception getValidationException() {
return validationException;
}


/**
* @return the ID of the Logout Request
*/
Expand Down
22 changes: 17 additions & 5 deletions core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public class LogoutResponse {
/**
* After validation, if it fails this property has the cause of the problem
*/
private String error;
private Exception validationException;

/**
* Constructs the LogoutResponse object.
Expand Down Expand Up @@ -168,7 +168,7 @@ public String getId() {
* @return if the SAML LogoutResponse is or not valid
*/
public Boolean isValid(String requestId) {
error = null;
validationException = null;

try {
if (this.logoutResponseDocument == null) {
Expand Down Expand Up @@ -270,9 +270,9 @@ public Boolean isValid(String requestId) {
LOGGER.debug("LogoutRequest validated --> " + logoutResponseString);
return true;
} catch (Exception e) {
error = e.getMessage();
validationException = e;
LOGGER.debug("LogoutResponse invalid --> " + logoutResponseString);
LOGGER.error(error);
LOGGER.error(validationException.getMessage());
return false;
}
}
Expand Down Expand Up @@ -451,6 +451,18 @@ private static StringBuilder getLogoutResponseTemplate() {
* @return the cause of the validation error
*/
public String getError() {
return error;
if (validationException != null) {
return validationException.getMessage();
}
return null;
}

/**
* After execute a validation process, if fails this method returns the Exception object
*
* @return the cause of the validation error
*/
public Exception getValidationException() {
return validationException;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2804,7 +2804,7 @@ public void testIsValidSignWithEmptyReferenceURI() throws IOException, Error, XP
}

/**
* Tests the getError method of SamlResponse
* Tests the getError and getValidationException methods of SamlResponse
*
* @throws ValidationError
* @throws SettingsException
Expand All @@ -2823,25 +2823,32 @@ public void testGetError() throws IOException, Error, XPathExpressionException,
String samlResponseEncoded = Util.getFileAsString("data/responses/response4.xml.base64");
SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
assertNull(samlResponse.getError());
assertNull(samlResponse.getValidationException());
samlResponse.isValid();
assertThat(samlResponse.getError(), containsString("SAML Response must contain 1 Assertion."));
assertTrue(samlResponse.getValidationException() instanceof ValidationError);

settings.setStrict(false);
samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
samlResponse.isValid();
assertThat(samlResponse.getError(), containsString("SAML Response must contain 1 Assertion."));
assertTrue(samlResponse.getValidationException() instanceof ValidationError);

samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64");
samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
assertNull(samlResponse.getError());
assertNull(samlResponse.getValidationException());
samlResponse.isValid();
assertNull(samlResponse.getError());
assertNull(samlResponse.getValidationException());

settings.setStrict(true);
samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
assertNull(samlResponse.getError());
assertNull(samlResponse.getValidationException());
samlResponse.isValid();
assertNull(samlResponse.getError());
assertNull(samlResponse.getValidationException());
}

private String loadAndEncode(String path) throws Exception
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ public void testIsValidNoCurrentURL() throws Exception {
}

/**
* Tests the getError method of LogoutRequest
* Tests the getError and getValidationException methods of LogoutRequest
*
* @throws Exception
*
Expand All @@ -828,14 +828,18 @@ public void testGetError() throws Exception {

LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
assertNull(logoutRequest.getError());
assertNull(logoutRequest.getValidationException());
logoutRequest.isValid();
assertThat(logoutRequest.getError(), containsString("The LogoutRequest was received at"));
assertTrue(logoutRequest.getValidationException() instanceof ValidationError);

settings.setStrict(false);
logoutRequest = new LogoutRequest(settings, httpRequest);
assertNull(logoutRequest.getError());
assertNull(logoutRequest.getValidationException());
logoutRequest.isValid();
assertNull(logoutRequest.getError());
assertNull(logoutRequest.getValidationException());
}

private static HttpRequest newHttpRequest(String requestURL, String samlRequestEncoded) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import com.onelogin.saml2.exception.ValidationError;
import java.io.IOException;
import java.net.URISyntaxException;

Expand Down Expand Up @@ -573,7 +574,7 @@ public void testIsValidNoLogoutResponse() throws IOException, XMLEntityException
}

/**
* Tests the getError method of LogoutResponse
* Tests the getError and getValidationException methods of LogoutResponse
*
* @throws IOException
* @throws URISyntaxException
Expand All @@ -591,14 +592,18 @@ public void testGetError() throws URISyntaxException, IOException, XMLEntityExce
HttpRequest httpRequest = newHttpRequest(requestURL, samlResponseEncoded);
LogoutResponse logoutResponse = new LogoutResponse(settings, httpRequest);
assertNull(logoutResponse.getError());
assertNull(logoutResponse.getValidationException());
logoutResponse.isValid();
assertThat(logoutResponse.getError(), containsString("The LogoutResponse was received at"));
assertTrue(logoutResponse.getValidationException() instanceof ValidationError);

settings.setStrict(false);
logoutResponse = new LogoutResponse(settings, httpRequest);
assertNull(logoutResponse.getError());
assertNull(logoutResponse.getValidationException());
logoutResponse.isValid();
assertNull(logoutResponse.getError());
assertNull(logoutResponse.getValidationException());
}

private static HttpRequest newHttpRequest(String requestURL, String samlResponseEncoded) {
Expand Down
15 changes: 15 additions & 0 deletions toolkit/src/main/java/com/onelogin/saml2/Auth.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ public class Auth {
*/
private String errorReason;

/**
* Exception of the last error.
*/
private Exception validationException;

/**
* The id of the last request (Authn or Logout) generated
*/
Expand Down Expand Up @@ -748,6 +753,7 @@ public void processResponse(String requestId) throws Exception {
LOGGER.error("processResponse error. invalid_response");
LOGGER.debug(" --> " + samlResponseParameter);
errorReason = samlResponse.getError();
validationException = samlResponse.getValidationException();
}
} else {
errors.add("invalid_binding");
Expand Down Expand Up @@ -790,6 +796,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
LOGGER.error("processSLO error. invalid_logout_response");
LOGGER.debug(" --> " + samlResponseParameter);
errorReason = logoutResponse.getError();
validationException = logoutResponse.getValidationException();
} else {
String status = logoutResponse.getStatus();
if (status == null || !status.equals(Constants.STATUS_SUCCESS)) {
Expand All @@ -812,6 +819,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
LOGGER.error("processSLO error. invalid_logout_request");
LOGGER.debug(" --> " + samlRequestParameter);
errorReason = logoutRequest.getError();
validationException = logoutRequest.getValidationException();
} else {
lastMessageId = logoutRequest.getId();
LOGGER.debug("processSLO success --> " + samlRequestParameter);
Expand Down Expand Up @@ -972,6 +980,13 @@ public String getLastErrorReason() {
return errorReason;
}

/**
* @return the exception for the last error
*/
public Exception getLastValidationException() {
return validationException;
}

/**
* @return the id of the last request generated (AuthnRequest or LogoutRequest),
* null if none
Expand Down
4 changes: 4 additions & 0 deletions toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,7 @@ public void testProcessSLORequestInvalid() throws Exception {
assertFalse(auth.getErrors().isEmpty());
assertTrue(auth.getErrors().contains("invalid_logout_request"));
assertThat(auth.getLastErrorReason(), containsString("The LogoutRequest was received at"));
assertTrue(auth.getLastValidationException() instanceof ValidationError);
}

/**
Expand Down Expand Up @@ -854,6 +855,7 @@ public void testIsAuthenticated() throws Exception {
expectedErrors.add("invalid_response");
assertEquals(expectedErrors, auth.getErrors());
assertEquals("SAML Response must contain 1 Assertion.", auth.getLastErrorReason());
assertTrue(auth.getLastValidationException() instanceof ValidationError);

samlResponseEncoded = Util.getFileAsString("data/responses/valid_encrypted_assertion.xml.base64");
when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded}));
Expand All @@ -867,6 +869,7 @@ public void testIsAuthenticated() throws Exception {
expectedErrors.add("invalid_response");
assertEquals(expectedErrors, auth2.getErrors());
assertThat(auth2.getLastErrorReason(), containsString("Invalid issuer in the Assertion/Response"));
assertTrue(auth2.getLastValidationException() instanceof ValidationError);

samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64");
when(request.getParameterMap()).thenReturn(singletonMap("SAMLResponse", new String[]{samlResponseEncoded}));
Expand All @@ -877,6 +880,7 @@ public void testIsAuthenticated() throws Exception {
assertTrue(auth3.isAuthenticated());
assertTrue(auth3.getErrors().isEmpty());
assertNull(auth3.getLastErrorReason());
assertNull(auth3.getLastValidationException());
}

/**
Expand Down