You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2018/07/16 16:52:12 UTC
[cxf-fediz] 01/02: FEDIZ-221 - Allow the user to cancel logout
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf-fediz.git
commit 819c7d0a7573f4cd55558b2a4db9063d7aa34e47
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Mon Jul 16 16:04:46 2018 +0100
FEDIZ-221 - Allow the user to cancel logout
---
.../webapp/WEB-INF/flows/saml-validate-request.xml | 2 +-
.../WEB-INF/views/signoutconfirmationresponse.jsp | 5 +
.../apache/cxf/fediz/systests/samlsso/IdpTest.java | 132 +++++++++++++++++++++
3 files changed, 138 insertions(+), 1 deletion(-)
diff --git a/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml b/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml
index ce6c253..ab80906 100644
--- a/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml
+++ b/services/idp/src/main/webapp/WEB-INF/flows/saml-validate-request.xml
@@ -223,7 +223,7 @@
<view-state id="viewSignoutConfirmation" view="signoutconfirmationresponse">
<transition on="submit" to="produceSAMLLogoutResponse"/>
- <!-- <transition on="cancel" to="redirect" /> -->
+ <transition on="cancel" to="viewBadLogoutRequestResponse" />
</view-state>
<action-state id="produceSAMLLogoutResponse">
diff --git a/services/idp/src/main/webapp/WEB-INF/views/signoutconfirmationresponse.jsp b/services/idp/src/main/webapp/WEB-INF/views/signoutconfirmationresponse.jsp
index 3e7a547..9d76ea6 100644
--- a/services/idp/src/main/webapp/WEB-INF/views/signoutconfirmationresponse.jsp
+++ b/services/idp/src/main/webapp/WEB-INF/views/signoutconfirmationresponse.jsp
@@ -17,6 +17,7 @@
Map<String, Application> rcm =
(Map<String, Application>) request.getSession().getAttribute(SigninParametersCacheAction.ACTIVE_APPLICATIONS);
String wreply = (String) request.getAttribute("wreply");
+ String samlAction = (String) request.getAttribute("SAMLRequest");
if (rcm == null) {
%>
@@ -55,6 +56,10 @@
<input type="hidden" name="wreply" value="<%= wreply%>" />
<input type="submit" name="_eventId_cancel" value="Cancel" />
<%
+ } else if (samlAction != null && !samlAction.isEmpty()) {
+ %>
+ <input type="submit" name="_eventId_cancel" value="Cancel" />
+ <%
}
%>
</form:form>
diff --git a/systests/samlsso/src/test/java/org/apache/cxf/fediz/systests/samlsso/IdpTest.java b/systests/samlsso/src/test/java/org/apache/cxf/fediz/systests/samlsso/IdpTest.java
index d83b06a..6aa8985 100644
--- a/systests/samlsso/src/test/java/org/apache/cxf/fediz/systests/samlsso/IdpTest.java
+++ b/systests/samlsso/src/test/java/org/apache/cxf/fediz/systests/samlsso/IdpTest.java
@@ -1879,6 +1879,138 @@ public class IdpTest {
webClient.close();
}
+ @org.junit.Test
+ public void testIdpLogoutCancelled() throws Exception {
+ OpenSAMLUtil.initSamlEngine();
+
+ // 1. First let's login to the IdP
+
+ // Create SAML AuthnRequest
+ Document doc = DOMUtils.createDocument();
+ doc.appendChild(doc.createElement("root"));
+ // Create the AuthnRequest
+ String consumerURL = "https://localhost:" + getRpHttpsPort() + "/"
+ + getServletContextName() + "/secure/fedservlet";
+ AuthnRequest authnRequest =
+ new DefaultAuthnRequestBuilder().createAuthnRequest(
+ null, "urn:org:apache:cxf:fediz:fedizhelloworld", consumerURL
+ );
+ authnRequest.setDestination("https://localhost:" + getIdpHttpsPort() + "/fediz-idp/saml");
+ signAuthnRequest(authnRequest);
+
+ Element authnRequestElement = OpenSAMLUtil.toDom(authnRequest, doc);
+ String authnRequestEncoded = encodeAuthnRequest(authnRequestElement);
+
+ String urlEncodedRequest = URLEncoder.encode(authnRequestEncoded, "UTF-8");
+
+ String relayState = UUID.randomUUID().toString();
+ String url = "https://localhost:" + getIdpHttpsPort() + "/fediz-idp/saml?";
+ url += SSOConstants.RELAY_STATE + "=" + relayState;
+ url += "&" + SSOConstants.SAML_REQUEST + "=" + urlEncodedRequest;
+
+ String user = "alice";
+ String password = "ecila";
+
+ CookieManager cookieManager = new CookieManager();
+
+ WebClient webClient = new WebClient();
+ webClient.setCookieManager(cookieManager);
+ webClient.getOptions().setUseInsecureSSL(true);
+ webClient.getCredentialsProvider().setCredentials(
+ new AuthScope("localhost", Integer.parseInt(getIdpHttpsPort())),
+ new UsernamePasswordCredentials(user, password));
+
+ webClient.getOptions().setJavaScriptEnabled(false);
+ HtmlPage idpPage = webClient.getPage(url);
+ webClient.getOptions().setJavaScriptEnabled(true);
+ Assert.assertEquals("IDP SignIn Response Form", idpPage.getTitleText());
+
+ org.opensaml.saml.saml2.core.Response samlResponse =
+ parseSAMLResponse(idpPage, relayState, consumerURL, authnRequest.getID());
+ String expected = "urn:oasis:names:tc:SAML:2.0:status:Success";
+ Assert.assertEquals(expected, samlResponse.getStatus().getStatusCode().getValue());
+ NameID nameID = samlResponse.getAssertions().get(0).getSubject().getNameID();
+ Assert.assertNotNull(nameID);
+ nameID.detach();
+
+ webClient.close();
+
+ // 2. now we logout from IdP - but cancel the logout
+
+ // Create SAML LogoutRequest
+ doc = DOMUtils.createDocument();
+ doc.appendChild(doc.createElement("root"));
+
+ Issuer issuer = SamlpRequestComponentBuilder.createIssuer("urn:org:apache:cxf:fediz:fedizhelloworld");
+ String destination = "https://localhost:" + getIdpHttpsPort() + "/fediz-idp/saml";
+ LogoutRequest logoutRequest =
+ SamlpRequestComponentBuilder.createLogoutRequest(SAMLVersion.VERSION_20, issuer, destination,
+ null, null, null, nameID);
+
+ signAuthnRequest(logoutRequest);
+
+ Element logoutRequestElement = OpenSAMLUtil.toDom(logoutRequest, doc);
+ String logoutRequestEncoded = encodeAuthnRequest(logoutRequestElement);
+
+ urlEncodedRequest = URLEncoder.encode(logoutRequestEncoded, "UTF-8");
+
+ relayState = UUID.randomUUID().toString();
+ String logoutURL = "https://localhost:" + getIdpHttpsPort() + "/fediz-idp/saml?";
+ logoutURL += SSOConstants.RELAY_STATE + "=" + relayState;
+ logoutURL += "&" + SSOConstants.SAML_REQUEST + "=" + urlEncodedRequest;
+
+ webClient = new WebClient();
+ webClient.setCookieManager(cookieManager);
+ webClient.getOptions().setUseInsecureSSL(true);
+ webClient.getCredentialsProvider().setCredentials(
+ new AuthScope("localhost", Integer.parseInt(getIdpHttpsPort())),
+ new UsernamePasswordCredentials(user, password));
+
+ webClient.getOptions().setJavaScriptEnabled(false);
+ idpPage = webClient.getPage(logoutURL);
+ webClient.getOptions().setJavaScriptEnabled(true);
+
+ Assert.assertEquals("IDP SignOut Confirmation Response Page", idpPage.getTitleText());
+
+ HtmlForm form = idpPage.getFormByName("signoutconfirmationresponseform");
+ HtmlSubmitInput button = form.getInputByName("_eventId_cancel");
+ HtmlPage signoutPage = button.click();
+
+ // Check Response
+ HtmlForm responseForm = signoutPage.getFormByName("samlsignoutresponseform");
+ Assert.assertEquals("https://localhost:8080/logout", responseForm.getActionAttribute());
+ String responseValue = responseForm.getInputByName("SAMLResponse").getAttributeNS(null, "value");
+ Assert.assertNotNull(responseValue);
+ String receivedRelayState = responseForm.getInputByName("RelayState").getAttributeNS(null, "value");
+ Assert.assertEquals(relayState, receivedRelayState);
+
+ byte[] deflatedToken = Base64Utility.decode(responseValue);
+ InputStream tokenStream = new ByteArrayInputStream(deflatedToken);
+ Document responseDoc = StaxUtils.read(new InputStreamReader(tokenStream, StandardCharsets.UTF_8));
+
+ LogoutResponse logoutResponse = (LogoutResponse)OpenSAMLUtil.fromDom(responseDoc.getDocumentElement());
+ Assert.assertNotNull(logoutResponse);
+ Assert.assertEquals("https://localhost:8080/logout", logoutResponse.getDestination());
+ String expectedIssuer = "https://localhost:" + getIdpHttpsPort() + "/fediz-idp/saml";
+ Assert.assertEquals(expectedIssuer, logoutResponse.getIssuer().getValue());
+ String success = "urn:oasis:names:tc:SAML:2.0:status:Requester";
+ Assert.assertEquals(success, logoutResponse.getStatus().getStatusCode().getValue());
+
+ webClient.close();
+
+ // 3. now we try to access the idp without authentication but with the existing cookies
+ // to see if we are really logged out - we should still be logged in as we cancelled the Logout process
+ webClient = new WebClient();
+ webClient.setCookieManager(cookieManager);
+ webClient.getOptions().setUseInsecureSSL(true);
+ webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
+ idpPage = webClient.getPage(url);
+
+ Assert.assertEquals(200, idpPage.getWebResponse().getStatusCode());
+
+ webClient.close();
+ }
+
private String encodeAuthnRequest(Element authnRequest) throws IOException {
String requestMessage = DOM2Writer.nodeToString(authnRequest);