Skip to content

Commit 7954478

Browse files
committed
#250 Add a stay parameter to Auth processSlo
1 parent 87b9786 commit 7954478

File tree

2 files changed

+117
-15
lines changed

2 files changed

+117
-15
lines changed

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

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,6 @@ public String logout(String returnTo, String nameId, String sessionIndex, Boolea
598598
* LogoutRequest.
599599
* @param nameIdSPNameQualifier The NameID SP Name Qualifier that will be set in
600600
* the LogoutRequest.
601-
*
602601
* @throws IOException
603602
* @throws XMLEntityException
604603
* @throws SettingsException
@@ -791,10 +790,14 @@ public void processResponse() throws Exception {
791790
* destroy it
792791
* @param requestId The ID of the LogoutRequest sent by this SP to the
793792
* IdP
793+
* @param stay True if we want to stay (returns the url string) False
794+
* to execute redirection
795+
*
796+
* @return the URL with the Logout Message if stay = True
794797
*
795798
* @throws Exception
796799
*/
797-
public void processSLO(Boolean keepLocalSession, String requestId) throws Exception {
800+
public String processSLO(Boolean keepLocalSession, String requestId, Boolean stay) throws Exception {
798801
final HttpRequest httpRequest = ServletUtils.makeHttpRequest(this.request);
799802

800803
final String samlRequestParameter = httpRequest.getParameter("SAMLRequest");
@@ -828,6 +831,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
828831
}
829832
}
830833
}
834+
return null;
831835
} else if (samlRequestParameter != null) {
832836
LogoutRequest logoutRequest = new LogoutRequest(settings, httpRequest);
833837
lastRequest = logoutRequest.getLogoutRequestXml();
@@ -837,6 +841,7 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
837841
LOGGER.debug(" --> " + samlRequestParameter);
838842
errorReason = logoutRequest.getError();
839843
validationException = logoutRequest.getValidationException();
844+
return null;
840845
} else {
841846
lastMessageId = logoutRequest.getId();
842847
LOGGER.debug("processSLO success --> " + samlRequestParameter);
@@ -869,8 +874,11 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
869874
}
870875

871876
String sloUrl = getSLOResponseUrl();
872-
LOGGER.debug("Logout response sent to " + sloUrl + " --> " + samlLogoutResponse);
873-
ServletUtils.sendRedirect(response, sloUrl, parameters);
877+
878+
if (!stay) {
879+
LOGGER.debug("Logout response sent to " + sloUrl + " --> " + samlLogoutResponse);
880+
}
881+
return ServletUtils.sendRedirect(response, sloUrl, parameters, stay);
874882
}
875883
} else {
876884
errors.add("invalid_binding");
@@ -880,6 +888,21 @@ public void processSLO(Boolean keepLocalSession, String requestId) throws Except
880888
}
881889
}
882890

891+
/**
892+
* Process the SAML Logout Response / Logout Request sent by the IdP.
893+
*
894+
* @param keepLocalSession When true will keep the local session, otherwise will
895+
* destroy it
896+
* @param requestId The ID of the LogoutRequest sent by this SP to the
897+
* IdP
898+
*
899+
*
900+
* @throws Exception
901+
*/
902+
public void processSLO(Boolean keepLocalSession, String requestId) throws Exception {
903+
processSLO(keepLocalSession, requestId, false);
904+
}
905+
883906
/**
884907
* Process the SAML Logout Response / Logout Request sent by the IdP.
885908
*

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

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static org.junit.Assert.assertEquals;
1111
import static org.junit.Assert.assertFalse;
1212
import static org.junit.Assert.assertNull;
13+
import static org.junit.Assert.assertNotNull;
1314
import static org.junit.Assert.assertThat;
1415
import static org.junit.Assert.assertTrue;
1516
import static org.mockito.Matchers.matches;
@@ -18,26 +19,18 @@
1819
import static org.mockito.Mockito.verify;
1920
import static org.mockito.Mockito.when;
2021

21-
import java.io.File;
2222
import java.io.FileInputStream;
2323
import java.io.FileNotFoundException;
2424
import java.io.IOException;
25-
import java.io.InputStream;
2625
import java.io.UnsupportedEncodingException;
2726
import java.net.URI;
2827
import java.net.URISyntaxException;
29-
import java.net.URLDecoder;
30-
import java.security.Key;
3128
import java.security.KeyStore;
3229
import java.security.KeyStoreException;
3330
import java.security.NoSuchAlgorithmException;
34-
import java.security.PrivateKey;
35-
import java.security.PublicKey;
3631
import java.security.UnrecoverableKeyException;
37-
import java.security.cert.Certificate;
3832
import java.security.cert.CertificateException;
3933
import java.util.ArrayList;
40-
import java.util.Base64;
4134
import java.util.HashMap;
4235
import java.util.List;
4336
import java.util.Map;
@@ -52,7 +45,6 @@
5245
import org.junit.rules.ExpectedException;
5346

5447
import com.onelogin.saml2.Auth;
55-
import com.onelogin.saml2.authn.SamlResponse;
5648
import com.onelogin.saml2.exception.Error;
5749
import com.onelogin.saml2.exception.ValidationError;
5850
import com.onelogin.saml2.exception.SettingsException;
@@ -642,7 +634,7 @@ public void testProcessSLORequestKeepSession() throws Exception {
642634
when(request.getSession()).thenReturn(session);
643635

644636
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
645-
when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded}));
637+
when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded}));
646638

647639
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
648640
Auth auth = new Auth(settings, request, response);
@@ -671,7 +663,7 @@ public void testProcessSLORequestRemoveSession() throws Exception {
671663
when(request.getSession()).thenReturn(session);
672664

673665
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
674-
when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded}));
666+
when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded}));
675667
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
676668
Auth auth = new Auth(settings, request, response);
677669
assertFalse(auth.isAuthenticated());
@@ -682,6 +674,93 @@ public void testProcessSLORequestRemoveSession() throws Exception {
682674
assertTrue(auth.getErrors().isEmpty());
683675
}
684676

677+
/**
678+
* Tests the processSLO methods of Auth
679+
* Case: process LogoutRequest, remove session, no stay
680+
*
681+
* @throws Exception
682+
*
683+
* @see com.onelogin.saml2.Auth#processSLO
684+
*/
685+
@Test
686+
public void testProcessSLORequestStay() throws Exception {
687+
HttpServletRequest request = mock(HttpServletRequest.class);
688+
HttpServletResponse response = mock(HttpServletResponse.class);
689+
HttpSession session = mock(HttpSession.class);
690+
when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php"));
691+
when(request.getSession()).thenReturn(session);
692+
693+
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
694+
when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded}));
695+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
696+
Auth auth = new Auth(settings, request, response);
697+
assertFalse(auth.isAuthenticated());
698+
assertTrue(auth.getErrors().isEmpty());
699+
auth.processSLO(false, null);
700+
verify(response).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*"));
701+
verify(session, times(1)).invalidate();
702+
assertTrue(auth.getErrors().isEmpty());
703+
}
704+
705+
/**
706+
* Tests the processSLO methods of Auth
707+
* Case: process LogoutRequest, remove session, stay = false
708+
*
709+
* @throws Exception
710+
*
711+
* @see com.onelogin.saml2.Auth#processSLO
712+
*/
713+
@Test
714+
public void testProcessSLORequestStayFalse() throws Exception {
715+
HttpServletRequest request = mock(HttpServletRequest.class);
716+
HttpServletResponse response = mock(HttpServletResponse.class);
717+
HttpSession session = mock(HttpSession.class);
718+
when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php"));
719+
when(request.getSession()).thenReturn(session);
720+
721+
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
722+
when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded}));
723+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
724+
Auth auth = new Auth(settings, request, response);
725+
assertFalse(auth.isAuthenticated());
726+
assertTrue(auth.getErrors().isEmpty());
727+
String target = auth.processSLO(false, null, false);
728+
verify(response).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*"));
729+
verify(response, times(1)).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*"));
730+
verify(session, times(1)).invalidate();
731+
assertTrue(auth.getErrors().isEmpty());
732+
assertThat(target, startsWith("http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php?SAMLResponse="));
733+
}
734+
735+
/**
736+
* Tests the processSLO methods of Auth
737+
* Case: process LogoutRequest, remove session, stay = true
738+
*
739+
* @throws Exception
740+
*
741+
* @see com.onelogin.saml2.Auth#processSLO
742+
*/
743+
@Test
744+
public void testProcessSLORequestStayTrue() throws Exception {
745+
HttpServletRequest request = mock(HttpServletRequest.class);
746+
HttpServletResponse response = mock(HttpServletResponse.class);
747+
HttpSession session = mock(HttpSession.class);
748+
when(request.getRequestURL()).thenReturn(new StringBuffer("http://stuff.com/endpoints/endpoints/sls.php"));
749+
when(request.getSession()).thenReturn(session);
750+
751+
String samlRequestEncoded = Util.getFileAsString("data/logout_requests/logout_request_deflated.xml.base64");
752+
when(request.getParameterMap()).thenReturn(singletonMap("SAMLRequest", new String[]{samlRequestEncoded}));
753+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
754+
Auth auth = new Auth(settings, request, response);
755+
assertFalse(auth.isAuthenticated());
756+
assertTrue(auth.getErrors().isEmpty());
757+
String target = auth.processSLO(false, null, true);
758+
verify(response, times(0)).sendRedirect(matches("http:\\/\\/idp.example.com\\/simplesaml\\/saml2\\/idp\\/SingleLogoutService.php\\?SAMLResponse=(.)*"));
759+
verify(session, times(1)).invalidate();
760+
assertTrue(auth.getErrors().isEmpty());
761+
assertThat(target, startsWith("http://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php?SAMLResponse="));
762+
}
763+
685764
/**
686765
* Tests the processSLO methods of Auth
687766
* Case: process LogoutRequest, with RelayState and sign response

0 commit comments

Comments
 (0)