You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2017/08/03 10:54:40 UTC
[2/2] syncope git commit: [SYNCOPE-1185] SAMLSSOResponseValidator in
action
[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ò <il...@apache.org>
Authored: Thu Aug 3 12:51:50 2017 +0200
Committer: Francesco Chicchiriccò <il...@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