From commits-return-49569-archive-asf-public=cust-asf.ponee.io@cxf.apache.org Fri Jul 13 19:03:09 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 774D0180789 for ; Fri, 13 Jul 2018 19:03:08 +0200 (CEST) Received: (qmail 90766 invoked by uid 500); 13 Jul 2018 17:03:07 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 90612 invoked by uid 99); 13 Jul 2018 17:03:07 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Jul 2018 17:03:07 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id CC09981DFA; Fri, 13 Jul 2018 17:03:06 +0000 (UTC) Date: Fri, 13 Jul 2018 17:03:08 +0000 To: "commits@cxf.apache.org" Subject: [cxf-fediz] 02/04: FEDIZ-221 - Check NonOnOrAfter with LogoutRequests MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: coheigea@apache.org In-Reply-To: <153150138671.2659.17495198941447949866@gitbox.apache.org> References: <153150138671.2659.17495198941447949866@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: cxf-fediz X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Rev: e1969c6037d29c987e0ccdf2e52f9032915c7fe4 X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20180713170306.CC09981DFA@gitbox.apache.org> 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 e1969c6037d29c987e0ccdf2e52f9032915c7fe4 Author: Colm O hEigeartaigh AuthorDate: Fri Jul 13 15:57:22 2018 +0100 FEDIZ-221 - Check NonOnOrAfter with LogoutRequests --- .../idp/beans/samlsso/AuthnRequestParser.java | 5 + .../service/idp/samlsso/SAMLLogoutRequest.java | 11 ++ .../apache/cxf/fediz/systests/samlsso/IdpTest.java | 112 +++++++++++++++++++++ 3 files changed, 128 insertions(+) diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.java index 49d5407..6b6b88a 100644 --- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.java +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/beans/samlsso/AuthnRequestParser.java @@ -27,6 +27,7 @@ import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Base64; import java.util.Collections; +import java.util.Date; import java.util.List; import org.w3c.dom.Document; @@ -121,6 +122,10 @@ public class AuthnRequestParser { WebUtils.putAttributeInFlowScope(context, IdpConstants.SAML_AUTHN_REQUEST, authnRequest); } else if (parsedRequest instanceof LogoutRequest) { SAMLLogoutRequest logoutRequest = new SAMLLogoutRequest((LogoutRequest)parsedRequest); + if (logoutRequest.getNotOnOrAfter() != null && (new Date()).after(logoutRequest.getNotOnOrAfter())) { + LOG.debug("The LogoutRequest is expired"); + throw new ProcessingException(TYPE.BAD_REQUEST); + } WebUtils.putAttributeInFlowScope(context, IdpConstants.SAML_LOGOUT_REQUEST, logoutRequest); } diff --git a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/samlsso/SAMLLogoutRequest.java b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/samlsso/SAMLLogoutRequest.java index 9e47764..c894190 100644 --- a/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/samlsso/SAMLLogoutRequest.java +++ b/services/idp-core/src/main/java/org/apache/cxf/fediz/service/idp/samlsso/SAMLLogoutRequest.java @@ -19,6 +19,8 @@ package org.apache.cxf.fediz.service.idp.samlsso; +import java.util.Date; + import org.opensaml.saml.saml2.core.LogoutRequest; /** @@ -32,9 +34,13 @@ public class SAMLLogoutRequest extends SAMLAbstractRequest { private static final long serialVersionUID = 4353024755428346545L; private String subjectNameId; + private Date notOnOrAfter; public SAMLLogoutRequest(LogoutRequest logoutRequest) { super(logoutRequest); + if (logoutRequest.getNotOnOrAfter() != null) { + notOnOrAfter = logoutRequest.getNotOnOrAfter().toDate(); + } if (logoutRequest.getNameID() != null) { subjectNameId = logoutRequest.getNameID().getValue(); @@ -44,4 +50,9 @@ public class SAMLLogoutRequest extends SAMLAbstractRequest { public String getSubjectNameId() { return subjectNameId; } + + public Date getNotOnOrAfter() { + return notOnOrAfter; + } + } 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 abfc43b..969a6aa 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 @@ -32,6 +32,7 @@ import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Base64; import java.util.Collections; +import java.util.Date; import java.util.UUID; import javax.servlet.ServletException; @@ -1747,6 +1748,117 @@ public class IdpTest { webClient.close(); } + @org.junit.Test + public void testIdpLogoutRequestExpired() 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 + + // 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"; + Date now = new Date(); + now.setTime(now.getTime() - (60L * 1000L)); + LogoutRequest logoutRequest = + SamlpRequestComponentBuilder.createLogoutRequest(SAMLVersion.VERSION_20, issuer, destination, + null, now, 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); + try { + webClient.getPage(logoutURL); + Assert.fail("Authentication failure expected"); + } catch (FailingHttpStatusCodeException ex) { + Assert.assertEquals(ex.getStatusCode(), 400); + } + 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 - it should work OK as our LogoutRequest was expired + 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);