Skip to content

Commit 56cea3f

Browse files
committed
Expose validation exceptions in Auth, LogoutRequest and LogoutResponse
Also add unit tests for validation exceptions
1 parent 2886c71 commit 56cea3f

8 files changed

Lines changed: 74 additions & 14 deletions

File tree

core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ public String getError() {
974974
}
975975

976976
/**
977-
* After execute a validation process, if fails this method returns the cause
977+
* After execute a validation process, if fails this method returns the Exception object
978978
*
979979
* @return the cause of the validation error
980980
*/

core/src/main/java/com/onelogin/saml2/logout/LogoutRequest.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public class LogoutRequest {
9898
/**
9999
* After validation, if it fails this property has the cause of the problem
100100
*/
101-
private String error;
101+
private Exception validationException;
102102

103103
/**
104104
* Constructs the LogoutRequest object.
@@ -366,7 +366,7 @@ private static StringBuilder getLogoutRequestTemplate() {
366366
* @throws Exception
367367
*/
368368
public Boolean isValid() throws Exception {
369-
error = null;
369+
validationException = null;
370370

371371
try {
372372
if (this.logoutRequestString == null || logoutRequestString.isEmpty()) {
@@ -474,9 +474,9 @@ public Boolean isValid() throws Exception {
474474
LOGGER.debug("LogoutRequest validated --> " + logoutRequestString);
475475
return true;
476476
} catch (Exception e) {
477-
error = e.getMessage();
477+
validationException = e;
478478
LOGGER.debug("LogoutRequest invalid --> " + logoutRequestString);
479-
LOGGER.error(error);
479+
LOGGER.error(validationException.getMessage());
480480
return false;
481481
}
482482
}
@@ -737,9 +737,22 @@ public static List<String> getSessionIndexes(String samlLogoutRequestString) thr
737737
* @return the cause of the validation error
738738
*/
739739
public String getError() {
740-
return error;
740+
if (validationException != null) {
741+
return validationException.getMessage();
742+
}
743+
return null;
741744
}
742745

746+
/**
747+
* After execute a validation process, if fails this method returns the Exception object
748+
*
749+
* @return the cause of the validation error
750+
*/
751+
public Exception getValidationException() {
752+
return validationException;
753+
}
754+
755+
743756
/**
744757
* @return the ID of the Logout Request
745758
*/

core/src/main/java/com/onelogin/saml2/logout/LogoutResponse.java

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public class LogoutResponse {
8282
/**
8383
* After validation, if it fails this property has the cause of the problem
8484
*/
85-
private String error;
85+
private Exception validationException;
8686

8787
/**
8888
* Constructs the LogoutResponse object.
@@ -168,7 +168,7 @@ public String getId() {
168168
* @return if the SAML LogoutResponse is or not valid
169169
*/
170170
public Boolean isValid(String requestId) {
171-
error = null;
171+
validationException = null;
172172

173173
try {
174174
if (this.logoutResponseDocument == null) {
@@ -270,9 +270,9 @@ public Boolean isValid(String requestId) {
270270
LOGGER.debug("LogoutRequest validated --> " + logoutResponseString);
271271
return true;
272272
} catch (Exception e) {
273-
error = e.getMessage();
273+
validationException = e;
274274
LOGGER.debug("LogoutResponse invalid --> " + logoutResponseString);
275-
LOGGER.error(error);
275+
LOGGER.error(validationException.getMessage());
276276
return false;
277277
}
278278
}
@@ -451,6 +451,18 @@ private static StringBuilder getLogoutResponseTemplate() {
451451
* @return the cause of the validation error
452452
*/
453453
public String getError() {
454-
return error;
454+
if (validationException != null) {
455+
return validationException.getMessage();
456+
}
457+
return null;
458+
}
459+
460+
/**
461+
* After execute a validation process, if fails this method returns the Exception object
462+
*
463+
* @return the cause of the validation error
464+
*/
465+
public Exception getValidationException() {
466+
return validationException;
455467
}
456468
}

core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2804,7 +2804,7 @@ public void testIsValidSignWithEmptyReferenceURI() throws IOException, Error, XP
28042804
}
28052805

28062806
/**
2807-
* Tests the getError method of SamlResponse
2807+
* Tests the getError and getValidationException methods of SamlResponse
28082808
*
28092809
* @throws ValidationError
28102810
* @throws SettingsException
@@ -2823,25 +2823,32 @@ public void testGetError() throws IOException, Error, XPathExpressionException,
28232823
String samlResponseEncoded = Util.getFileAsString("data/responses/response4.xml.base64");
28242824
SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
28252825
assertNull(samlResponse.getError());
2826+
assertNull(samlResponse.getValidationException());
28262827
samlResponse.isValid();
28272828
assertThat(samlResponse.getError(), containsString("SAML Response must contain 1 Assertion."));
2829+
assertTrue(samlResponse.getValidationException() instanceof ValidationError);
28282830

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

28342837
samlResponseEncoded = Util.getFileAsString("data/responses/valid_response.xml.base64");
28352838
samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
28362839
assertNull(samlResponse.getError());
2840+
assertNull(samlResponse.getValidationException());
28372841
samlResponse.isValid();
28382842
assertNull(samlResponse.getError());
2843+
assertNull(samlResponse.getValidationException());
28392844

28402845
settings.setStrict(true);
28412846
samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
28422847
assertNull(samlResponse.getError());
2848+
assertNull(samlResponse.getValidationException());
28432849
samlResponse.isValid();
28442850
assertNull(samlResponse.getError());
2851+
assertNull(samlResponse.getValidationException());
28452852
}
28462853

28472854
private String loadAndEncode(String path) throws Exception

core/src/test/java/com/onelogin/saml2/test/logout/LogoutRequestTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ public void testIsValidNoCurrentURL() throws Exception {
812812
}
813813

814814
/**
815-
* Tests the getError method of LogoutRequest
815+
* Tests the getError and getValidationException methods of LogoutRequest
816816
*
817817
* @throws Exception
818818
*
@@ -828,14 +828,18 @@ public void testGetError() throws Exception {
828828

829829
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
830830
assertNull(logoutRequest.getError());
831+
assertNull(logoutRequest.getValidationException());
831832
logoutRequest.isValid();
832833
assertThat(logoutRequest.getError(), containsString("The LogoutRequest was received at"));
834+
assertTrue(logoutRequest.getValidationException() instanceof ValidationError);
833835

834836
settings.setStrict(false);
835837
logoutRequest = new LogoutRequest(settings, httpRequest);
836838
assertNull(logoutRequest.getError());
839+
assertNull(logoutRequest.getValidationException());
837840
logoutRequest.isValid();
838841
assertNull(logoutRequest.getError());
842+
assertNull(logoutRequest.getValidationException());
839843
}
840844

841845
private static HttpRequest newHttpRequest(String requestURL, String samlRequestEncoded) {

core/src/test/java/com/onelogin/saml2/test/logout/LogoutResponseTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import static org.junit.Assert.assertNotEquals;
1010
import static org.junit.Assert.assertTrue;
1111

12+
import com.onelogin.saml2.exception.ValidationError;
1213
import java.io.IOException;
1314
import java.net.URISyntaxException;
1415

@@ -573,7 +574,7 @@ public void testIsValidNoLogoutResponse() throws IOException, XMLEntityException
573574
}
574575

575576
/**
576-
* Tests the getError method of LogoutResponse
577+
* Tests the getError and getValidationException methods of LogoutResponse
577578
*
578579
* @throws IOException
579580
* @throws URISyntaxException
@@ -591,14 +592,18 @@ public void testGetError() throws URISyntaxException, IOException, XMLEntityExce
591592
HttpRequest httpRequest = newHttpRequest(requestURL, samlResponseEncoded);
592593
LogoutResponse logoutResponse = new LogoutResponse(settings, httpRequest);
593594
assertNull(logoutResponse.getError());
595+
assertNull(logoutResponse.getValidationException());
594596
logoutResponse.isValid();
595597
assertThat(logoutResponse.getError(), containsString("The LogoutResponse was received at"));
598+
assertTrue(logoutResponse.getValidationException() instanceof ValidationError);
596599

597600
settings.setStrict(false);
598601
logoutResponse = new LogoutResponse(settings, httpRequest);
599602
assertNull(logoutResponse.getError());
603+
assertNull(logoutResponse.getValidationException());
600604
logoutResponse.isValid();
601605
assertNull(logoutResponse.getError());
606+
assertNull(logoutResponse.getValidationException());
602607
}
603608

604609
private static HttpRequest newHttpRequest(String requestURL, String samlResponseEncoded) {

toolkit/src/main/java/com/onelogin/saml2/Auth.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ public class Auth {
133133
*/
134134
private String errorReason;
135135

136+
/**
137+
* Exception of the last error.
138+
*/
139+
private Exception validationException;
140+
136141
/**
137142
* The id of the last request (Authn or Logout) generated
138143
*/
@@ -748,6 +753,7 @@ public void processResponse(String requestId) throws Exception {
748753
LOGGER.error("processResponse error. invalid_response");
749754
LOGGER.debug(" --> " + samlResponseParameter);
750755
errorReason = samlResponse.getError();
756+
validationException = samlResponse.getValidationException();
751757
}
752758
} else {
753759
errors.add("invalid_binding");
@@ -790,6 +796,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
790796
LOGGER.error("processSLO error. invalid_logout_response");
791797
LOGGER.debug(" --> " + samlResponseParameter);
792798
errorReason = logoutResponse.getError();
799+
validationException = logoutResponse.getValidationException();
793800
} else {
794801
String status = logoutResponse.getStatus();
795802
if (status == null || !status.equals(Constants.STATUS_SUCCESS)) {
@@ -812,6 +819,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
812819
LOGGER.error("processSLO error. invalid_logout_request");
813820
LOGGER.debug(" --> " + samlRequestParameter);
814821
errorReason = logoutRequest.getError();
822+
validationException = logoutRequest.getValidationException();
815823
} else {
816824
lastMessageId = logoutRequest.getId();
817825
LOGGER.debug("processSLO success --> " + samlRequestParameter);
@@ -972,6 +980,13 @@ public String getLastErrorReason() {
972980
return errorReason;
973981
}
974982

983+
/**
984+
* @return the exception for the last error
985+
*/
986+
public Exception getLastValidationException() {
987+
return validationException;
988+
}
989+
975990
/**
976991
* @return the id of the last request generated (AuthnRequest or LogoutRequest),
977992
* null if none

toolkit/src/test/java/com/onelogin/saml2/test/AuthTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,7 @@ public void testProcessSLORequestInvalid() throws Exception {
713713
assertFalse(auth.getErrors().isEmpty());
714714
assertTrue(auth.getErrors().contains("invalid_logout_request"));
715715
assertThat(auth.getLastErrorReason(), containsString("The LogoutRequest was received at"));
716+
assertTrue(auth.getLastValidationException() instanceof ValidationError);
716717
}
717718

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

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

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

882886
/**

0 commit comments

Comments
 (0)