Author: coheigea
Date: Mon Mar 5 12:53:19 2012
New Revision: 1297038
URL: http://svn.apache.org/viewvc?rev=1297038&view=rev
Log:
[CXF-4160] - Support signing a SAML token using the requested signature and
canonicalization algorithm
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/service/EncryptionProperties.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java?rev=1297038&r1=1297037&r2=1297038&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java
Mon Mar 5 12:53:19 2012
@@ -18,16 +18,33 @@
*/
package org.apache.cxf.sts;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ws.security.WSConstants;
+
/**
* This class contains various configuration properties that can be used to
sign an issued token,
* or generate a symmetric key in the STS.
*/
public class SignatureProperties {
+ private String signatureAlgorithm = WSConstants.RSA_SHA1;
+ private String c14nAlgorithm = WSConstants.C14N_EXCL_OMIT_COMMENTS;
+ private List<String> acceptedSignatureAlgorithms = new ArrayList<String>();
+ private List<String> acceptedC14nAlgorithms = new ArrayList<String>();
private boolean useKeyValue;
private long keySize = 256;
private long minimumKeySize = 128;
private long maximumKeySize = 512;
+ public SignatureProperties() {
+ // Default signature algorithms
+ acceptedSignatureAlgorithms.add(signatureAlgorithm);
+
+ // Default c14n algorithms
+ acceptedC14nAlgorithms.add(c14nAlgorithm);
+ }
+
/**
* Get whether a KeyValue is used to refer to a a certificate used to sign
an issued token.
* The default is false.
@@ -90,5 +107,72 @@ public class SignatureProperties {
public void setMaximumKeySize(long maximumKeySize) {
this.maximumKeySize = maximumKeySize;
}
+
+ /**
+ * Get the signature algorithm to use
+ */
+ public String getSignatureAlgorithm() {
+ return signatureAlgorithm;
+ }
+
+ /**
+ * Set the signature algorithm to use
+ */
+ public void setSignatureAlgorithm(String signatureAlgorithm) {
+ this.signatureAlgorithm = signatureAlgorithm;
+ }
+
+ /**
+ * Get the c14n algorithm to use
+ */
+ public String getC14nAlgorithm() {
+ return c14nAlgorithm;
+ }
+
+ /**
+ * Set the c14n algorithm to use
+ */
+ public void setC14nAlgorithm(String c14nAlgorithm) {
+ this.c14nAlgorithm = c14nAlgorithm;
+ }
+
+ /**
+ * Get the list of accepted signature algorithms. A request can contain a
wst:SignatureAlgorithm
+ * uri to use to sign an issued token. The algorithm specified must be
contained in this list.
+ * The default algorithms are RSA-SHA1.
+ */
+ public List<String> getAcceptedSignatureAlgorithms() {
+ return acceptedSignatureAlgorithms;
+ }
+
+ /**
+ * Set the list of accepted signature algorithms. A request can contain a
wst:SignatureAlgorithm
+ * uri to use to sign an issued token. The algorithm specified must be
contained in this list.
+ * The default algorithms are RSA-SHA1.
+ */
+ public void setAcceptedSignatureAlgorithms(
+ List<String> acceptedSignatureAlgorithms
+ ) {
+ this.acceptedSignatureAlgorithms = acceptedSignatureAlgorithms;
+ }
+
+
+ /**
+ * Get the list of accepted c14n algorithms. A request can contain a
wst:CanonicalizationAlgorithm
+ * uri to use for c14n in an issued token. The algorithm specified must be
contained in this list.
+ * The default algorithms are C14N_EXCL_OMIT_COMMENTS.
+ */
+ public List<String> getAcceptedC14nAlgorithms() {
+ return acceptedC14nAlgorithms;
+ }
+
+ /**
+ * Set the list of accepted c14n algorithms. A request can contain a
wst:CanonicalizationAlgorithm
+ * uri to use for c14n in an issued token. The algorithm specified must be
contained in this list.
+ * The default algorithms are C14N_EXCL_OMIT_COMMENTS.
+ */
+ public void setAcceptedC14nAlgorithms(List<String> acceptedC14nAlgorithms)
{
+ this.acceptedC14nAlgorithms = acceptedC14nAlgorithms;
+ }
-}
\ No newline at end of file
+}
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/service/EncryptionProperties.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/service/EncryptionProperties.java?rev=1297038&r1=1297037&r2=1297038&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/service/EncryptionProperties.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/service/EncryptionProperties.java
Mon Mar 5 12:53:19 2012
@@ -42,6 +42,9 @@ public class EncryptionProperties {
acceptedEncryptionAlgorithms.add(WSConstants.AES_128);
acceptedEncryptionAlgorithms.add(WSConstants.AES_192);
acceptedEncryptionAlgorithms.add(WSConstants.AES_256);
+ acceptedEncryptionAlgorithms.add(WSConstants.AES_128_GCM);
+ acceptedEncryptionAlgorithms.add(WSConstants.AES_192_GCM);
+ acceptedEncryptionAlgorithms.add(WSConstants.AES_256_GCM);
// Default key wrap algorithms
acceptedKeyWrapAlgorithms.add(WSConstants.KEYTRANSPORT_RSA15);
@@ -107,7 +110,7 @@ public class EncryptionProperties {
/**
* Set the list of accepted encryption algorithms. A request can contain a
wst:EncryptionAlgorithm
* uri to use to encrypt an issued token. The algorithm specified must be
contained in this list.
- * The default algorithms are 3-DES, AES-128, AES-192 and AES-256.
+ * The default algorithms are 3-DES, AES-128, AES-128 GCM, AES-192,
AES-192 GCM, AES-256 and AES-256 GCM.
*/
public void setAcceptedEncryptionAlgorithms(List<String>
acceptedEncryptionAlgorithms) {
this.acceptedEncryptionAlgorithms = acceptedEncryptionAlgorithms;
@@ -116,7 +119,7 @@ public class EncryptionProperties {
/**
* Get the list of accepted encryption algorithms. A request can contain a
wst:EncryptionAlgorithm
* uri to use to encrypt an issued token. The algorithm specified must be
contained in this list.
- * The default algorithms are 3-DES, AES-128, AES-192 and AES-256.
+ * The default algorithms are 3-DES, AES-128, AES-128 GCM, AES-192,
AES-192 GCM, AES-256 and AES-256 GCM.
*/
public List<String> getAcceptedEncryptionAlgorithms() {
return acceptedEncryptionAlgorithms;
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java?rev=1297038&r1=1297037&r2=1297038&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java
Mon Mar 5 12:53:19 2012
@@ -326,7 +326,35 @@ public class SAMLTokenProvider implement
if (samlRealm.getSignatureProperties() != null) {
signatureProperties = samlRealm.getSignatureProperties();
}
- }
+ }
+
+ // Get the signature algorithm to use
+ String signatureAlgorithm =
tokenParameters.getKeyRequirements().getSignatureAlgorithm();
+ if (signatureAlgorithm == null) {
+ // If none then default to what is configured
+ signatureAlgorithm =
signatureProperties.getSignatureAlgorithm();
+ } else {
+ List<String> supportedAlgorithms =
+ signatureProperties.getAcceptedSignatureAlgorithms();
+ if (!supportedAlgorithms.contains(signatureAlgorithm)) {
+ signatureAlgorithm =
signatureProperties.getSignatureAlgorithm();
+ LOG.fine("SignatureAlgorithm not supported, defaulting to:
" + signatureAlgorithm);
+ }
+ }
+
+ // Get the c14n algorithm to use
+ String c14nAlgorithm =
tokenParameters.getKeyRequirements().getC14nAlgorithm();
+ if (c14nAlgorithm == null) {
+ // If none then default to what is configured
+ c14nAlgorithm = signatureProperties.getC14nAlgorithm();
+ } else {
+ List<String> supportedAlgorithms =
+ signatureProperties.getAcceptedC14nAlgorithms();
+ if (!supportedAlgorithms.contains(c14nAlgorithm)) {
+ c14nAlgorithm = signatureProperties.getC14nAlgorithm();
+ LOG.fine("C14nAlgorithm not supported, defaulting to: " +
c14nAlgorithm);
+ }
+ }
// If alias not defined, get the default of the SignatureCrypto
if ((alias == null || "".equals(alias)) && (signatureCrypto !=
null)) {
@@ -341,7 +369,9 @@ public class SAMLTokenProvider implement
LOG.fine("Signing SAML Token");
boolean useKeyValue = signatureProperties.isUseKeyValue();
- assertion.signAssertion(alias, password, signatureCrypto,
useKeyValue);
+ assertion.signAssertion(
+ alias, password, signatureCrypto, useKeyValue, c14nAlgorithm,
signatureAlgorithm
+ );
}
return assertion;
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java?rev=1297038&r1=1297037&r2=1297038&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java
Mon Mar 5 12:53:19 2012
@@ -40,6 +40,7 @@ import org.apache.cxf.security.SecurityC
import org.apache.cxf.sts.QNameConstants;
import org.apache.cxf.sts.STSConstants;
import org.apache.cxf.sts.STSPropertiesMBean;
+import org.apache.cxf.sts.SignatureProperties;
import org.apache.cxf.sts.StaticSTSProperties;
import org.apache.cxf.sts.common.PasswordCallbackHandler;
import org.apache.cxf.sts.common.TestUtils;
@@ -563,6 +564,92 @@ public class IssueSamlUnitTest extends o
assertFalse(foundReference);
}
+ /**
+ * Test to successfully issue a Saml 2 token using a specified C14n
Algorithm.
+ */
+ @org.junit.Test
+ public void testIssueSaml2DifferentC14nToken() throws Exception {
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+
+ // Add Token Provider
+ List<TokenProvider> providerList = new ArrayList<TokenProvider>();
+ providerList.add(new SAMLTokenProvider());
+ issueOperation.setTokenProviders(providerList);
+
+ // Add Service
+ ServiceMBean service = new StaticService();
+
service.setEndpoints(Collections.singletonList("http://dummy-service.com/dummy"));
+ issueOperation.setServices(Collections.singletonList(service));
+
+ // Add STSProperties object
+ STSPropertiesMBean stsProperties = new StaticSTSProperties();
+ Crypto crypto = CryptoFactory.getInstance(getEncryptionProperties());
+ stsProperties.setEncryptionCrypto(crypto);
+ stsProperties.setSignatureCrypto(crypto);
+ stsProperties.setEncryptionUsername("myservicekey");
+ stsProperties.setSignatureUsername("mystskey");
+ stsProperties.setCallbackHandler(new PasswordCallbackHandler());
+ stsProperties.setIssuer("STS");
+
+ SignatureProperties sigProperties = new SignatureProperties();
+ List<String> acceptedC14nAlgorithms = new ArrayList<String>();
+ acceptedC14nAlgorithms.add(WSConstants.C14N_EXCL_OMIT_COMMENTS);
+ acceptedC14nAlgorithms.add(WSConstants.C14N_EXCL_WITH_COMMENTS);
+ sigProperties.setAcceptedC14nAlgorithms(acceptedC14nAlgorithms);
+ stsProperties.setSignatureProperties(sigProperties);
+
+ issueOperation.setStsProperties(stsProperties);
+
+ // Mock up a request
+ RequestSecurityTokenType request = new RequestSecurityTokenType();
+ JAXBElement<String> tokenType =
+ new JAXBElement<String>(
+ QNameConstants.TOKEN_TYPE, String.class,
WSConstants.WSS_SAML2_TOKEN_TYPE
+ );
+ request.getAny().add(tokenType);
+
request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy"));
+ JAXBElement<String> c14nAlg =
+ new JAXBElement<String>(
+ QNameConstants.C14N_ALGORITHM, String.class,
WSConstants.C14N_EXCL_WITH_COMMENTS
+ );
+ request.getAny().add(c14nAlg);
+
+ // Mock up message context
+ MessageImpl msg = new MessageImpl();
+ WrappedMessageContext msgCtx = new WrappedMessageContext(msg);
+ msgCtx.put(
+ SecurityContext.class.getName(),
+ createSecurityContext(new CustomTokenPrincipal("alice"))
+ );
+ WebServiceContextImpl webServiceContext = new
WebServiceContextImpl(msgCtx);
+
+ // Issue a token
+ RequestSecurityTokenResponseCollectionType response =
+ issueOperation.issue(request, webServiceContext);
+ List<RequestSecurityTokenResponseType> securityTokenResponse =
+ response.getRequestSecurityTokenResponse();
+ assertTrue(!securityTokenResponse.isEmpty());
+
+ // Test the generated token.
+ Element assertion = null;
+ for (Object tokenObject : securityTokenResponse.get(0).getAny()) {
+ if (tokenObject instanceof JAXBElement<?>
+ &&
REQUESTED_SECURITY_TOKEN.equals(((JAXBElement<?>)tokenObject).getName())) {
+ RequestedSecurityTokenType rstType =
+
(RequestedSecurityTokenType)((JAXBElement<?>)tokenObject).getValue();
+ assertion = (Element)rstType.getAny();
+ break;
+ }
+ }
+
+ assertNotNull(assertion);
+ String tokenString = DOM2Writer.nodeToString(assertion);
+ assertTrue(tokenString.contains("AttributeStatement"));
+ assertTrue(tokenString.contains("alice"));
+ assertTrue(tokenString.contains(SAML2Constants.CONF_BEARER));
+ assertTrue(tokenString.contains(WSConstants.C14N_EXCL_WITH_COMMENTS));
+ }
+
/*
* Create a security context object
*/
Modified:
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java?rev=1297038&r1=1297037&r2=1297038&view=diff
==============================================================================
---
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
(original)
+++
cxf/branches/2.5.x-fixes/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java
Mon Mar 5 12:53:19 2012
@@ -19,6 +19,8 @@
package org.apache.cxf.sts.token.provider;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
import org.w3c.dom.Element;
@@ -27,6 +29,7 @@ import org.apache.cxf.jaxws.context.WebS
import org.apache.cxf.jaxws.context.WrappedMessageContext;
import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.sts.STSConstants;
+import org.apache.cxf.sts.STSPropertiesMBean;
import org.apache.cxf.sts.SignatureProperties;
import org.apache.cxf.sts.StaticSTSProperties;
import org.apache.cxf.sts.common.PasswordCallbackHandler;
@@ -417,6 +420,46 @@ public class SAMLProviderKeyTypeTest ext
assertFalse(tokenString.contains(SAML1Constants.CONF_HOLDER_KEY));
}
+ /**
+ * Create a default Saml2 Bearer Assertion using a specified C14n Algorithm
+ */
+ @org.junit.Test
+ public void testDefaultSaml2BearerDifferentC14nAssertion() throws
Exception {
+ TokenProvider samlTokenProvider = new SAMLTokenProvider();
+ TokenProviderParameters providerParameters =
+ createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE,
STSConstants.BEARER_KEY_KEYTYPE);
+ KeyRequirements keyRequirements =
providerParameters.getKeyRequirements();
+
+ keyRequirements.setC14nAlgorithm(WSConstants.C14N_EXCL_WITH_COMMENTS);
+
+ // This will fail as the requested c14n algorithm is rejected
+ TokenProviderResponse providerResponse =
samlTokenProvider.createToken(providerParameters);
+ assertTrue(providerResponse != null);
+ assertTrue(providerResponse.getToken() != null &&
providerResponse.getTokenId() != null);
+
+ Element token = providerResponse.getToken();
+ String tokenString = DOM2Writer.nodeToString(token);
+ assertFalse(tokenString.contains(WSConstants.C14N_EXCL_WITH_COMMENTS));
+ assertTrue(tokenString.contains(WSConstants.C14N_EXCL_OMIT_COMMENTS));
+
+ STSPropertiesMBean stsProperties =
providerParameters.getStsProperties();
+ SignatureProperties sigProperties = new SignatureProperties();
+ List<String> acceptedC14nAlgorithms = new ArrayList<String>();
+ acceptedC14nAlgorithms.add(WSConstants.C14N_EXCL_OMIT_COMMENTS);
+ acceptedC14nAlgorithms.add(WSConstants.C14N_EXCL_WITH_COMMENTS);
+ sigProperties.setAcceptedC14nAlgorithms(acceptedC14nAlgorithms);
+ stsProperties.setSignatureProperties(sigProperties);
+
+ // This will succeed as the requested c14n algorithm is accepted
+ providerResponse = samlTokenProvider.createToken(providerParameters);
+ assertTrue(providerResponse != null);
+ assertTrue(providerResponse.getToken() != null &&
providerResponse.getTokenId() != null);
+
+ token = providerResponse.getToken();
+ tokenString = DOM2Writer.nodeToString(token);
+ assertTrue(tokenString.contains(WSConstants.C14N_EXCL_WITH_COMMENTS));
+ }
+
private TokenProviderParameters createProviderParameters(
String tokenType, String keyType
) throws WSSecurityException {