[SYNCOPE-1185] SAMLSSOResponseValidator in action

Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/e624f369
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/e624f369
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/e624f369

Branch: refs/heads/master
Commit: e624f369d6a2df12ddc516e6b50ff5cb9d30747b
Parents: e3467bf
Author: Francesco Chicchiriccò <ilgro...@apache.org>
Authored: Thu Aug 3 12:51:50 2017 +0200
Committer: Francesco Chicchiriccò <ilgro...@apache.org>
Committed: Thu Aug 3 12:53:58 2017 +0200

----------------------------------------------------------------------
 .../saml2lsp/agent/AbstractSAML2SPServlet.java  |  10 ++-
 .../ext/saml2lsp/agent/AssertionConsumer.java   |   7 +-
 .../syncope/ext/saml2lsp/agent/Logout.java      |   6 +-
 .../common/lib/to/SAML2ReceivedResponseTO.java  |  31 ++++++++
 .../apache/syncope/core/logic/SAML2SPLogic.java |  33 ++++----
 .../core/logic/saml2/SAML2ReaderWriter.java     |  25 +++++-
 fit/core-reference/pom.xml                      |   2 -
 .../apache/syncope/fit/core/SAML2ITCase.java    |  76 ++++++++++---------
 .../src/test/resources/stsrealm_a.jks           | Bin 2061 -> 0 bytes
 9 files changed, 130 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
----------------------------------------------------------------------
diff --git 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
index d84bcd7..ecc14fe 100644
--- 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
+++ 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
@@ -76,7 +76,12 @@ public abstract class AbstractSAML2SPServlet extends 
HttpServlet {
         }
     }
 
-    protected SAML2ReceivedResponseTO extract(final InputStream response) 
throws IOException {
+    protected SAML2ReceivedResponseTO extract(
+            final String spEntityID,
+            final String urlContext,
+            final String clientAddress,
+            final InputStream response) throws IOException {
+
         String strForm = IOUtils.toString(response);
         MultivaluedMap<String, String> params = 
JAXRSUtils.getStructuredParams(strForm, "&", false, false);
 
@@ -90,6 +95,9 @@ public abstract class AbstractSAML2SPServlet extends 
HttpServlet {
         LOG.debug("Received Relay State: {}", relayState);
 
         SAML2ReceivedResponseTO receivedResponseTO = new 
SAML2ReceivedResponseTO();
+        receivedResponseTO.setSpEntityID(spEntityID);
+        receivedResponseTO.setUrlContext(urlContext);
+        receivedResponseTO.setClientAddress(clientAddress);
         receivedResponseTO.setSamlResponse(samlResponse);
         receivedResponseTO.setRelayState(relayState);
         return receivedResponseTO;

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
----------------------------------------------------------------------
diff --git 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
index 698aa7f..a2fec3a 100644
--- 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
+++ 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
@@ -25,6 +25,7 @@ import javax.servlet.ServletException;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
 import org.apache.syncope.common.rest.api.service.SAML2SPService;
@@ -42,7 +43,11 @@ public class AssertionConsumer extends 
AbstractSAML2SPServlet {
                 getAttribute(Constants.SYNCOPE_ANONYMOUS_CLIENT);
         try {
             SAML2LoginResponseTO responseTO = 
anonymous.getService(SAML2SPService.class).
-                    validateLoginResponse(extract(request.getInputStream()));
+                    validateLoginResponse(extract(
+                            
StringUtils.substringBefore(request.getRequestURL().toString(), "/saml2sp"),
+                            "saml2sp",
+                            request.getRemoteAddr(),
+                            request.getInputStream()));
 
             request.getSession(true).setAttribute(Constants.SAML2SPJWT, 
responseTO.getAccessToken());
             request.getSession(true).setAttribute(Constants.SAML2SPJWT_EXPIRE, 
responseTO.getAccessTokenExpiryTime());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Logout.java
----------------------------------------------------------------------
diff --git 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Logout.java
 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Logout.java
index a8fe481..8008b0c 100644
--- 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Logout.java
+++ 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/Logout.java
@@ -125,7 +125,11 @@ public class Logout extends AbstractSAML2SPServlet {
             throws ServletException, IOException {
 
         // process POST binding logout response
-        SAML2ReceivedResponseTO receivedResponse = 
extract(request.getInputStream());
+        SAML2ReceivedResponseTO receivedResponse = extract(
+                
StringUtils.substringBefore(request.getRequestURL().toString(), "/saml2sp"),
+                "saml2sp",
+                request.getRemoteAddr(),
+                request.getInputStream());
         doLogout(receivedResponse, request, response);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
----------------------------------------------------------------------
diff --git 
a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
 
b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
index 3d5d9b4..4ea2dec 100644
--- 
a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
+++ 
b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.to;
 
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.AbstractBaseBean;
 
 @XmlRootElement(name = "saml2ReceivedResponse")
@@ -28,10 +29,40 @@ public class SAML2ReceivedResponseTO extends 
AbstractBaseBean {
 
     private static final long serialVersionUID = 6102419133516694822L;
 
+    private String spEntityID;
+
+    private String urlContext;
+
+    private String clientAddress;
+
     private String samlResponse;
 
     private String relayState;
 
+    public String getSpEntityID() {
+        return spEntityID;
+    }
+
+    public void setSpEntityID(final String spEntityID) {
+        this.spEntityID = StringUtils.appendIfMissing(spEntityID, "/");
+    }
+
+    public String getUrlContext() {
+        return urlContext;
+    }
+
+    public void setUrlContext(final String urlContext) {
+        this.urlContext = urlContext;
+    }
+
+    public String getClientAddress() {
+        return clientAddress;
+    }
+
+    public void setClientAddress(final String clientAddress) {
+        this.clientAddress = clientAddress;
+    }
+
     public String getSamlResponse() {
         return samlResponse;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
----------------------------------------------------------------------
diff --git 
a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
 
b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index 28a1ef0..a9b63ed 100644
--- 
a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ 
b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -117,7 +117,6 @@ import org.opensaml.xmlsec.keyinfo.KeyInfoGenerator;
 import org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.stereotype.Component;
 import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
@@ -176,6 +175,10 @@ public class SAML2SPLogic extends 
AbstractSAML2Logic<AbstractBaseBean> {
     @Resource(name = "syncopeJWTSSOProviderDelegate")
     private JwsSignatureVerifier jwsSignatureVerifier;
 
+    private String getAssertionConsumerURL(final String spEntityID, final 
String urlContext) {
+        return spEntityID + urlContext + "/assertion-consumer";
+    }
+
     @PreAuthorize("hasRole('" + StandardEntitlement.ANONYMOUS + "')")
     public void getMetadata(final String spEntityID, final String urlContext, 
final OutputStream os) {
         check();
@@ -209,7 +212,7 @@ public class SAML2SPLogic extends 
AbstractSAML2Logic<AbstractBaseBean> {
                 AssertionConsumerService assertionConsumerService = new 
AssertionConsumerServiceBuilder().buildObject();
                 assertionConsumerService.setIndex(bindingType.ordinal());
                 assertionConsumerService.setBinding(bindingType.getUri());
-                assertionConsumerService.setLocation(spEntityID + urlContext + 
"/assertion-consumer");
+                
assertionConsumerService.setLocation(getAssertionConsumerURL(spEntityID, 
urlContext));
                 
spSSODescriptor.getAssertionConsumerServices().add(assertionConsumerService);
                 spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor);
 
@@ -450,24 +453,19 @@ public class SAML2SPLogic extends 
AbstractSAML2Logic<AbstractBaseBean> {
             throw sce;
         }
 
-        // 3. further checks:
-        //   3a. the SAML Reponse's InResponseTo
-        if 
(!relayState.getJwtClaims().getSubject().equals(samlResponse.getInResponseTo()))
 {
-            throw new IllegalArgumentException("Unmatching request ID: " + 
samlResponse.getInResponseTo());
-        }
-        //   3b. the SAML Response status
-        if 
(!StatusCode.SUCCESS.equals(samlResponse.getStatus().getStatusCode().getValue()))
 {
-            throw new BadCredentialsException("The SAML IdP replied with "
-                    + samlResponse.getStatus().getStatusCode().getValue());
-        }
-
-        // 4. validate the SAML response and, if needed, decrypt the provided 
assertion(s)
+        // 3. validate the SAML response and, if needed, decrypt the provided 
assertion(s)
         SAML2IdPEntity idp = getIdP(samlResponse.getIssuer().getValue());
         if (idp.getConnObjectKeyItem() == null) {
             throw new IllegalArgumentException("No mapping provided for SAML 
2.0 IdP '" + idp.getId() + "'");
         }
         try {
-            saml2rw.validate(samlResponse, idp.getTrustStore());
+            saml2rw.validate(
+                    samlResponse,
+                    idp,
+                    getAssertionConsumerURL(response.getSpEntityID(), 
response.getUrlContext()),
+                    response.getClientAddress(),
+                    relayState.getJwtClaims().getSubject(),
+                    response.getSpEntityID());
         } catch (Exception e) {
             LOG.error("While validating AuthnResponse", e);
             SyncopeClientException sce = 
SyncopeClientException.build(ClientExceptionType.Unknown);
@@ -475,7 +473,7 @@ public class SAML2SPLogic extends 
AbstractSAML2Logic<AbstractBaseBean> {
             throw sce;
         }
 
-        // 5. prepare the result: find matching user (if any) and return the 
received attributes
+        // 4. prepare the result: find matching user (if any) and return the 
received attributes
         SAML2LoginResponseTO responseTO = new SAML2LoginResponseTO();
         responseTO.setIdp(idp.getId());
         responseTO.setSloSupported(idp.getSLOLocation(idp.getBindingType()) != 
null);
@@ -541,7 +539,8 @@ public class SAML2SPLogic extends 
AbstractSAML2Logic<AbstractBaseBean> {
         
responseTO.setUsername(userDAO.find(matchingUsers.get(0)).getUsername());
 
         responseTO.setNameID(nameID.getValue());
-        // 6. generate JWT for further access
+
+        // 5. generate JWT for further access
         Map<String, Object> claims = new HashMap<>();
         claims.put(JWT_CLAIM_IDP_ENTITYID, idp.getId());
         claims.put(JWT_CLAIM_NAMEID_FORMAT, nameID.getFormat());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
----------------------------------------------------------------------
diff --git 
a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
 
b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
index 429c088..1852a39 100644
--- 
a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
+++ 
b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
@@ -28,7 +28,6 @@ import java.io.Writer;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.security.InvalidKeyException;
-import java.security.KeyStore;
 import java.util.Base64;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
@@ -44,8 +43,10 @@ import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 import org.apache.cxf.rs.security.saml.DeflateEncoderDecoder;
 import org.apache.cxf.rs.security.saml.sso.SAMLProtocolResponseValidator;
+import org.apache.cxf.rs.security.saml.sso.SAMLSSOResponseValidator;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.syncope.common.lib.SSOConstants;
+import org.apache.syncope.common.lib.types.SAML2BindingType;
 import org.apache.syncope.core.logic.init.SAML2SPLoader;
 import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
@@ -91,6 +92,8 @@ public class SAML2ReaderWriter {
 
     private SAMLProtocolResponseValidator protocolValidator;
 
+    private SAMLSSOResponseValidator ssoResponseValidator;
+
     private SAMLSPCallbackHandler callbackHandler;
 
     public void init() {
@@ -109,6 +112,8 @@ public class SAML2ReaderWriter {
         protocolValidator = new SAMLProtocolResponseValidator();
         protocolValidator.setKeyInfoMustBeAvailable(true);
 
+        ssoResponseValidator = new SAMLSSOResponseValidator();
+
         callbackHandler = new SAMLSPCallbackHandler(loader.getKeyPass());
     }
 
@@ -205,14 +210,28 @@ public class SAML2ReaderWriter {
         return Base64.getEncoder().encodeToString(deflatedBytes);
     }
 
-    public void validate(final Response samlResponse, final KeyStore 
idpTrustStore) throws WSSecurityException {
+    public void validate(
+            final Response samlResponse,
+            final SAML2IdPEntity idp,
+            final String assertionConsumerURL,
+            final String clientAddress,
+            final String requestId,
+            final String spEntityID)
+            throws WSSecurityException {
+
         // validate the SAML response and, if needed, decrypt the provided 
assertion(s)
         Merlin crypto = new Merlin();
         crypto.setKeyStore(loader.getKeyStore());
-        crypto.setTrustStore(idpTrustStore);
+        crypto.setTrustStore(idp.getTrustStore());
 
         protocolValidator.validateSamlResponse(samlResponse, crypto, 
callbackHandler);
 
+        ssoResponseValidator.setAssertionConsumerURL(assertionConsumerURL);
+        ssoResponseValidator.setIssuerIDP(idp.getId());
+        ssoResponseValidator.setRequestId(requestId);
+        ssoResponseValidator.setSpIdentifier(spEntityID);
+        ssoResponseValidator.validateSamlResponse(samlResponse, 
idp.getBindingType() == SAML2BindingType.POST);
+
         if (LOG.isDebugEnabled()) {
             try {
                 StringWriter writer = new StringWriter();

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/fit/core-reference/pom.xml
----------------------------------------------------------------------
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 0772ccb..5762a33 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -363,7 +363,6 @@ under the License.
         <filtering>true</filtering>
         <excludes>
           <exclude>keystore</exclude>
-          <exclude>**/*.jks</exclude>
         </excludes>
       </testResource>
       <testResource>
@@ -371,7 +370,6 @@ under the License.
         <filtering>false</filtering>
         <includes>
           <include>keystore</include>
-          <include>**/*.jks</include>
         </includes>
       </testResource>
       <testResource>

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index 68626d0..f0cd386 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -165,7 +165,8 @@ public class SAML2ITCase extends AbstractITCase {
         Assume.assumeTrue(SAML2SPDetector.isSAML2SPAvailable());
 
         Optional<SAML2IdPTO> ssoCircleOpt =
-            saml2IdPService.list().stream().filter(o -> 
"https://idp.ssocircle.com".equals(o.getEntityID())).findFirst();
+                saml2IdPService.list().stream().filter(o -> 
"https://idp.ssocircle.com".equals(o.getEntityID())).
+                        findFirst();
         assertTrue(ssoCircleOpt.isPresent());
 
         SAML2IdPTO ssoCircle = ssoCircleOpt.get();
@@ -195,8 +196,7 @@ public class SAML2ITCase extends AbstractITCase {
 
         // Get a valid login request for the Fediz realm
         SAML2SPService saml2Service = 
anonymous.getService(SAML2SPService.class);
-        SAML2RequestTO loginRequest =
-                saml2Service.createLoginRequest(ADDRESS, 
"urn:org:apache:cxf:fediz:idp:realm-A");
+        SAML2RequestTO loginRequest = saml2Service.createLoginRequest(ADDRESS, 
"urn:org:apache:cxf:fediz:idp:realm-A");
         assertNotNull(loginRequest);
 
         assertEquals("https://localhost:8443/fediz-idp/saml/up";, 
loginRequest.getIdpServiceAddress());
@@ -206,11 +206,13 @@ public class SAML2ITCase extends AbstractITCase {
 
         // Check a null relaystate
         SAML2ReceivedResponseTO response = new SAML2ReceivedResponseTO();
+        response.setSpEntityID("http://recipient.apache.org/";);
+        response.setUrlContext("saml2sp");
         try {
             saml2Service.validateLoginResponse(response);
             fail("Failure expected on no Relay State");
-        } catch (SyncopeClientException ex) {
-            assertTrue(ex.getMessage().contains("No Relay State was 
provided"));
+        } catch (SyncopeClientException e) {
+            assertTrue(e.getMessage().contains("No Relay State was provided"));
         }
 
         // Check a null Response
@@ -218,16 +220,17 @@ public class SAML2ITCase extends AbstractITCase {
         try {
             saml2Service.validateLoginResponse(response);
             fail("Failure expected on no SAML Response");
-        } catch (SyncopeClientException ex) {
-            assertTrue(ex.getMessage().contains("No SAML Response was 
provided"));
+        } catch (SyncopeClientException e) {
+            assertTrue(e.getMessage().contains("No SAML Response was 
provided"));
         }
 
         // Create a SAML Response using WSS4J
-        Document doc = DOMUtils.newDocument();
         JwsJwtCompactConsumer relayState = new 
JwsJwtCompactConsumer(response.getRelayState());
         String inResponseTo = relayState.getJwtClaims().getSubject();
 
         org.opensaml.saml.saml2.core.Response samlResponse = 
createResponse(inResponseTo);
+
+        Document doc = DOMUtils.newDocument();
         Element responseElement = OpenSAMLUtil.toDom(samlResponse, doc);
         String responseStr = DOM2Writer.nodeToString(responseElement);
 
@@ -239,26 +242,27 @@ public class SAML2ITCase extends AbstractITCase {
     }
 
     @Test
-    @org.junit.Ignore
-    public void testUnsignedAssertionInLoginResponse() throws Exception {
+    public void unsignedAssertionInLoginResponse() throws Exception {
         Assume.assumeTrue(SAML2SPDetector.isSAML2SPAvailable());
 
         // Get a valid login request for the Fediz realm
         SAML2SPService saml2Service = 
anonymous.getService(SAML2SPService.class);
-        SAML2RequestTO loginRequest =
-                saml2Service.createLoginRequest(ADDRESS, 
"urn:org:apache:cxf:fediz:idp:realm-A");
+        SAML2RequestTO loginRequest = saml2Service.createLoginRequest(ADDRESS, 
"urn:org:apache:cxf:fediz:idp:realm-A");
         assertNotNull(loginRequest);
 
         SAML2ReceivedResponseTO response = new SAML2ReceivedResponseTO();
+        response.setSpEntityID("http://recipient.apache.org/";);
+        response.setUrlContext("saml2sp");
         response.setRelayState(loginRequest.getRelayState());
 
         // Create a SAML Response using WSS4J
-        Document doc = DOMUtils.newDocument();
         JwsJwtCompactConsumer relayState = new 
JwsJwtCompactConsumer(response.getRelayState());
         String inResponseTo = relayState.getJwtClaims().getSubject();
 
         org.opensaml.saml.saml2.core.Response samlResponse =
                 createResponse(inResponseTo, false, 
SAML2Constants.CONF_SENDER_VOUCHES);
+
+        Document doc = DOMUtils.newDocument();
         Element responseElement = OpenSAMLUtil.toDom(samlResponse, doc);
         String responseStr = DOM2Writer.nodeToString(responseElement);
 
@@ -267,35 +271,35 @@ public class SAML2ITCase extends AbstractITCase {
         try {
             saml2Service.validateLoginResponse(response);
             fail("Failure expected on an unsigned Assertion");
-        } catch (SyncopeClientException ex) {
-            // expected
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
         }
     }
 
     @Test
-    @org.junit.Ignore
-    public void testLoginResponseWrappingAttack() throws Exception {
+    public void loginResponseWrappingAttack() throws Exception {
         Assume.assumeTrue(SAML2SPDetector.isSAML2SPAvailable());
 
         // Get a valid login request for the Fediz realm
         SAML2SPService saml2Service = 
anonymous.getService(SAML2SPService.class);
-        SAML2RequestTO loginRequest =
-                saml2Service.createLoginRequest(ADDRESS, 
"urn:org:apache:cxf:fediz:idp:realm-A");
+        SAML2RequestTO loginRequest = saml2Service.createLoginRequest(ADDRESS, 
"urn:org:apache:cxf:fediz:idp:realm-A");
         assertNotNull(loginRequest);
 
         SAML2ReceivedResponseTO response = new SAML2ReceivedResponseTO();
+        response.setSpEntityID("http://recipient.apache.org/";);
+        response.setUrlContext("saml2sp");
         response.setRelayState(loginRequest.getRelayState());
 
         // Create a SAML Response using WSS4J
-        Document doc = DOMUtils.newDocument();
         JwsJwtCompactConsumer relayState = new 
JwsJwtCompactConsumer(response.getRelayState());
         String inResponseTo = relayState.getJwtClaims().getSubject();
 
         org.opensaml.saml.saml2.core.Response samlResponse = 
createResponse(inResponseTo);
-        Element responseElement = OpenSAMLUtil.toDom(samlResponse, doc);
 
-        doc.appendChild(responseElement);
+        Document doc = DOMUtils.newDocument();
+        Element responseElement = OpenSAMLUtil.toDom(samlResponse, doc);
         assertNotNull(responseElement);
+        doc.appendChild(responseElement);
 
         // Get Assertion Element
         Element assertionElement =
@@ -326,9 +330,12 @@ public class SAML2ITCase extends AbstractITCase {
 
         // Validate the SAML Response
         
response.setSamlResponse(java.util.Base64.getEncoder().encodeToString(responseStr.getBytes()));
-        SAML2LoginResponseTO loginResponse = 
saml2Service.validateLoginResponse(response);
-        assertNotNull(loginResponse.getAccessToken());
-        assertEquals("puccini", loginResponse.getNameID());
+        try {
+            saml2Service.validateLoginResponse(response);
+            fail("Failure expected on an unsigned Assertion");
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
     }
 
     private org.opensaml.saml.saml2.core.Response createResponse(final String 
inResponseTo) throws Exception {
@@ -340,9 +347,8 @@ public class SAML2ITCase extends AbstractITCase {
 
         Status status = SAML2PResponseComponentBuilder.createStatus(
                 SAMLProtocolResponseValidator.SAML2_STATUSCODE_SUCCESS, null);
-        org.opensaml.saml.saml2.core.Response response =
-                SAML2PResponseComponentBuilder.createSAMLResponse(
-                        inResponseTo, "urn:org:apache:cxf:fediz:idp:realm-A", 
status);
+        org.opensaml.saml.saml2.core.Response response = 
SAML2PResponseComponentBuilder.createSAMLResponse(
+                inResponseTo, "urn:org:apache:cxf:fediz:idp:realm-A", status);
         response.setDestination("http://recipient.apache.org";);
 
         // Create an AuthenticationAssertion
@@ -353,9 +359,9 @@ public class SAML2ITCase extends AbstractITCase {
 
         SubjectConfirmationDataBean subjectConfirmationData = new 
SubjectConfirmationDataBean();
         subjectConfirmationData.setAddress("http://apache.org";);
-        subjectConfirmationData.setInResponseTo("12345");
+        subjectConfirmationData.setInResponseTo(inResponseTo);
         subjectConfirmationData.setNotAfter(new DateTime().plusMinutes(5));
-        subjectConfirmationData.setRecipient("http://recipient.apache.org";);
+        
subjectConfirmationData.setRecipient("http://recipient.apache.org/saml2sp/assertion-consumer";);
         callbackHandler.setSubjectConfirmationData(subjectConfirmationData);
 
         ConditionsBean conditions = new ConditionsBean();
@@ -363,7 +369,7 @@ public class SAML2ITCase extends AbstractITCase {
         conditions.setNotAfter(new DateTime().plusMinutes(5));
 
         AudienceRestrictionBean audienceRestriction = new 
AudienceRestrictionBean();
-        
audienceRestriction.setAudienceURIs(Collections.singletonList("http://service.apache.org";));
+        
audienceRestriction.setAudienceURIs(Collections.singletonList("http://recipient.apache.org/";));
         
conditions.setAudienceRestrictions(Collections.singletonList(audienceRestriction));
         callbackHandler.setConditions(conditions);
 
@@ -374,12 +380,12 @@ public class SAML2ITCase extends AbstractITCase {
         if (signAssertion) {
             Crypto issuerCrypto = new Merlin();
             KeyStore keyStore = KeyStore.getInstance("JKS");
-            ClassLoader loader = Loader.getClassLoader(SAML2ITCase.class);
-            InputStream input = Merlin.loadInputStream(loader, 
"stsrealm_a.jks");
-            keyStore.load(input, "storepass".toCharArray());
+            ClassLoader loader = Loader.getClassLoader(getClass());
+            InputStream input = Merlin.loadInputStream(loader, "keystore");
+            keyStore.load(input, "changeit".toCharArray());
             ((Merlin) issuerCrypto).setKeyStore(keyStore);
 
-            assertion.signAssertion("realma", "realma", issuerCrypto, false);
+            assertion.signAssertion("sp", "changeit", issuerCrypto, false);
         }
 
         response.getAssertions().add(assertion.getSaml2());

http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/fit/core-reference/src/test/resources/stsrealm_a.jks
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/resources/stsrealm_a.jks 
b/fit/core-reference/src/test/resources/stsrealm_a.jks
deleted file mode 100644
index fde2928..0000000
Binary files a/fit/core-reference/src/test/resources/stsrealm_a.jks and 
/dev/null differ

Reply via email to