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 2020/06/15 15:35:50 UTC
[cxf-fediz] branch master updated: FEDIZ-247 - Adding an @Ignore'd
unit test
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
The following commit(s) were added to refs/heads/master by this push:
new 811ed1f FEDIZ-247 - Adding an @Ignore'd unit test
811ed1f is described below
commit 811ed1ffcae3dc3cdc4d9f7b41a5d80fc74c21ab
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Mon Jun 15 16:35:24 2020 +0100
FEDIZ-247 - Adding an @Ignore'd unit test
---
.../cxf/fediz/core/samlsso/SAMLResponseTest.java | 185 ++++++++++++++++++++-
.../src/test/resources/fediz_test_config_saml.xml | 32 ++++
2 files changed, 213 insertions(+), 4 deletions(-)
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
index f612e6f..3e83eb8 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
@@ -26,6 +26,7 @@ import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
+import java.security.Key;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Base64;
@@ -33,6 +34,8 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.servlet.http.HttpServletRequest;
@@ -78,6 +81,10 @@ import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
import org.apache.wss4j.common.saml.builder.SAML2Constants;
import org.apache.wss4j.common.util.DOM2Writer;
import org.apache.wss4j.dom.WSConstants;
+import org.apache.xml.security.encryption.EncryptedData;
+import org.apache.xml.security.encryption.EncryptedKey;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.keys.content.X509Data;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.opensaml.saml.common.SAMLObjectContentReference;
@@ -96,6 +103,8 @@ import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
@@ -1225,7 +1234,7 @@ public class SAMLResponseTest {
NodeList assertionNodes =
policyElement.getElementsByTagNameNS(WSConstants.SAML2_NS, "Assertion");
- Assert.assertTrue(assertionNodes != null && assertionNodes.getLength() == 1);
+ assertTrue(assertionNodes != null && assertionNodes.getLength() == 1);
Element assertionElement = (Element)assertionNodes.item(0);
@@ -1547,6 +1556,58 @@ public class SAMLResponseTest {
}
}
+ @org.junit.Test
+ @org.junit.Ignore // TODO https://issues.apache.org/jira/browse/FEDIZ-247
+ public void validateEncryptedSAMLResponse() throws Exception {
+ // Mock up a Request
+ //FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+ FedizContext config =
+ getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+
+ String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+ String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+ RequestState requestState = new RequestState(TEST_REQUEST_URL,
+ TEST_IDP_ISSUER,
+ requestId,
+ TEST_REQUEST_URL,
+ (String)config.getProtocol().getIssuer(),
+ null,
+ relayState,
+ System.currentTimeMillis());
+
+ // Create SAML Response
+ SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+ callbackHandler.setAlsoAddAuthnStatement(true);
+ callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+ callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+ callbackHandler.setIssuer(TEST_IDP_ISSUER);
+ callbackHandler.setSubjectName(TEST_USER);
+ String responseStr = createSamlResponseStr(callbackHandler, requestId, true);
+
+ HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+ EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+ EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+ EasyMock.replay(req);
+
+ FedizRequest wfReq = new FedizRequest();
+ wfReq.setResponseToken(responseStr);
+ wfReq.setState(relayState);
+ wfReq.setRequest(req);
+ wfReq.setRequestState(requestState);
+
+ FedizProcessor wfProc = new SAMLProcessorImpl();
+ FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+ Assert.assertEquals("Principal name wrong", TEST_USER,
+ wfRes.getUsername());
+ Assert.assertEquals("Issuer wrong", TEST_IDP_ISSUER, wfRes.getIssuer());
+ Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+ .size());
+ Assert.assertEquals("Audience wrong", TEST_REQUEST_URL, wfRes.getAudience());
+ assertClaims(wfRes.getClaims(), ClaimTypes.COUNTRY);
+ }
+
private String createSamlResponseStr(String requestId) throws Exception {
// Create SAML Assertion
SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
@@ -1561,6 +1622,12 @@ public class SAMLResponseTest {
private String createSamlResponseStr(AbstractSAMLCallbackHandler saml2CallbackHandler,
String requestId) throws Exception {
+ return createSamlResponseStr(saml2CallbackHandler, requestId, false);
+ }
+
+ private String createSamlResponseStr(AbstractSAMLCallbackHandler saml2CallbackHandler,
+ String requestId,
+ boolean encryptAssertion) throws Exception {
ConditionsBean cp = new ConditionsBean();
AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
@@ -1578,6 +1645,11 @@ public class SAMLResponseTest {
SAMLCallback samlCallback = new SAMLCallback();
SAMLUtil.doSAMLCallback(saml2CallbackHandler, samlCallback);
SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+ if (encryptAssertion) {
+ Element response = createEncryptedSamlResponse(assertion, "mystskey", true, requestId);
+ return encodeResponse(response);
+ }
Element response = createSamlResponse(assertion, "mystskey", true, requestId);
return encodeResponse(response);
}
@@ -1596,7 +1668,6 @@ public class SAMLResponseTest {
}
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
- Document doc = docBuilder.newDocument();
Status status =
SAML2PResponseComponentBuilder.createStatus(
@@ -1606,15 +1677,71 @@ public class SAMLResponseTest {
SAML2PResponseComponentBuilder.createSAMLResponse(requestID,
assertion.getIssuerString(),
status);
-
response.getAssertions().add(assertion.getSaml2());
+ Document doc = docBuilder.newDocument();
Element policyElement = OpenSAMLUtil.toDom(response, doc);
doc.appendChild(policyElement);
return policyElement;
}
+ private Element createEncryptedSamlResponse(SamlAssertionWrapper assertion, String alias,
+ boolean sign, String requestID)
+ throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
+ WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)};
+ cbPasswordHandler.handle(cb);
+ String password = cb[0].getPassword();
+
+ if (sign) {
+ assertion.signAssertion(alias, password, crypto, false);
+ }
+
+ DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+
+ Status status =
+ SAML2PResponseComponentBuilder.createStatus(
+ "urn:oasis:names:tc:SAML:2.0:status:Success", null
+ );
+ Response response =
+ SAML2PResponseComponentBuilder.createSAMLResponse(requestID,
+ assertion.getIssuerString(),
+ status);
+
+ Document assertionDoc = docBuilder.newDocument();
+ Element elem = assertion.toDOM(assertionDoc);
+
+ Element encryptedAssertionElement =
+ assertionDoc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
+ encryptedAssertionElement.setAttributeNS(
+ WSConstants.XMLNS_NS, "xmlns", WSConstants.SAML2_NS
+ );
+ encryptedAssertionElement.appendChild(elem);
+ assertionDoc.appendChild(encryptedAssertionElement);
+
+ // Encrypt the Assertion
+ KeyGenerator keygen = KeyGenerator.getInstance("AES");
+ keygen.init(256);
+ SecretKey secretKey = keygen.generateKey();
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias("mystskey");
+ X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+ assertTrue(certs != null && certs.length > 0 && certs[0] != null);
+
+ encryptElement(assertionDoc, elem, WSConstants.AES_256, secretKey,
+ WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false);
+
+ Document doc = docBuilder.newDocument();
+ Element policyElement = OpenSAMLUtil.toDom(response, doc);
+ Element statusElement =
+ (Element)policyElement.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:protocol",
+ "Status").item(0);
+ assertNotNull(statusElement);
+ policyElement.appendChild(doc.importNode(encryptedAssertionElement, true));
+
+ return policyElement;
+ }
+
private Element createLogoutResponse(String statusValue, String destination,
boolean sign, String requestID) throws Exception {
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
@@ -1704,7 +1831,7 @@ public class SAMLResponseTest {
break;
}
}
- Assert.assertTrue(found);
+ assertTrue(found);
}
private String encodeResponse(Element response) throws IOException {
@@ -1715,5 +1842,55 @@ public class SAMLResponseTest {
return Base64.getEncoder().encodeToString(deflatedBytes);
}
+ private void encryptElement(
+ Document document,
+ Element elementToEncrypt,
+ String algorithm,
+ Key encryptingKey,
+ String keyTransportAlgorithm,
+ X509Certificate wrappingCert,
+ boolean content
+ ) throws Exception {
+ XMLCipher cipher = XMLCipher.getInstance(algorithm);
+ cipher.init(XMLCipher.ENCRYPT_MODE, encryptingKey);
+
+ if (wrappingCert != null) {
+ XMLCipher newCipher = XMLCipher.getInstance(keyTransportAlgorithm);
+ newCipher.init(XMLCipher.WRAP_MODE, wrappingCert.getPublicKey());
+
+ EncryptedKey encryptedKey = newCipher.encryptKey(document, encryptingKey);
+ // Create a KeyInfo for the EncryptedKey
+ org.apache.xml.security.keys.KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
+ if (encryptedKeyKeyInfo == null) {
+ encryptedKeyKeyInfo = new org.apache.xml.security.keys.KeyInfo(document);
+ encryptedKeyKeyInfo.getElement().setAttributeNS(
+ "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
+ );
+ encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
+ }
+
+ X509Data x509Data = new X509Data(document);
+ // x509Data.addCertificate(wrappingCert);
+ x509Data.addIssuerSerial(wrappingCert.getIssuerX500Principal().getName(),
+ wrappingCert.getSerialNumber());
+ encryptedKeyKeyInfo.add(x509Data);
+
+ // Create a KeyInfo for the EncryptedData
+ EncryptedData builder = cipher.getEncryptedData();
+ org.apache.xml.security.keys.KeyInfo builderKeyInfo = builder.getKeyInfo();
+ if (builderKeyInfo == null) {
+ builderKeyInfo = new org.apache.xml.security.keys.KeyInfo(document);
+ builderKeyInfo.getElement().setAttributeNS(
+ "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
+ );
+ builder.setKeyInfo(builderKeyInfo);
+ }
+
+ builderKeyInfo.add(encryptedKey);
+ }
+
+ cipher.doFinal(document, elementToEncrypt, content);
+ }
+
}
diff --git a/plugins/core/src/test/resources/fediz_test_config_saml.xml b/plugins/core/src/test/resources/fediz_test_config_saml.xml
index 9147445..ff84520 100644
--- a/plugins/core/src/test/resources/fediz_test_config_saml.xml
+++ b/plugins/core/src/test/resources/fediz_test_config_saml.xml
@@ -332,4 +332,36 @@
<logoutURL>secure/logout</logoutURL>
<logoutRedirectTo>/redir.html</logoutRedirectTo>
</contextConfig>
+
+ <contextConfig name="ROOT_DECRYPTION">
+ <audienceUris>
+ <audienceItem>http://host_one:port/url</audienceItem>
+ </audienceUris>
+ <certificateStores>
+ <trustManager>
+ <keyStore file="ststrust.jks" password="storepass"
+ type="JKS" />
+ </trustManager>
+ </certificateStores>
+ <trustedIssuers>
+ <issuer certificateValidation="PeerTrust" />
+ </trustedIssuers>
+ <tokenDecryptionKey keyPassword="stskpass" keyAlias="mystskey">
+ <keyStore file="stsstore.jks" password="stsspass" type="JKS" />
+ </tokenDecryptionKey>
+
+ <maximumClockSkew>1000</maximumClockSkew>
+ <protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:type="samlProtocolType" version="1.2">
+ <issuer>http://url_to_the_issuer</issuer>
+ <roleDelimiter>;</roleDelimiter>
+ <roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+ <claimTypesRequested>
+ <claimType type="a particular claim type" optional="true" />
+ </claimTypesRequested>
+ </protocol>
+
+ <logoutURL>secure/logout</logoutURL>
+ <logoutRedirectTo>/redir.html</logoutRedirectTo>
+ </contextConfig>
</FedizConfig>