Repository: cxf Updated Branches: refs/heads/master 8f4799b5b -> 9e87ede2d
[CXF-5651] - Support issuing SAML Tokens from the STS with strong digest algorithms Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/9e87ede2 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/9e87ede2 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/9e87ede2 Branch: refs/heads/master Commit: 9e87ede2de0119ad557d6a9f8f8299766c52adc7 Parents: 8f4799b Author: Colm O hEigeartaigh <[email protected]> Authored: Wed Mar 26 10:50:32 2014 +0000 Committer: Colm O hEigeartaigh <[email protected]> Committed: Wed Mar 26 10:50:32 2014 +0000 ---------------------------------------------------------------------- .../org/apache/cxf/sts/SignatureProperties.java | 17 ++++ .../sts/token/provider/SAMLTokenProvider.java | 3 +- .../cxf/sts/operation/IssueSamlUnitTest.java | 92 +++++++++++++++++++- .../token/provider/SAMLProviderKeyTypeTest.java | 68 ++++++++++++++- 4 files changed, 177 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/9e87ede2/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java index 71d654c..d446e12 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/SignatureProperties.java @@ -36,6 +36,7 @@ public class SignatureProperties { private long keySize = 256; private long minimumKeySize = 128; private long maximumKeySize = 512; + private String digestAlgorithm = WSConstants.SHA1; public SignatureProperties() { // Default signature algorithms @@ -174,5 +175,21 @@ public class SignatureProperties { public void setAcceptedC14nAlgorithms(List<String> acceptedC14nAlgorithms) { this.acceptedC14nAlgorithms = acceptedC14nAlgorithms; } + + /** + * Get the Digest algorithm to use for Signature + * @return the Digest algorithm to use for Signature + */ + public String getDigestAlgorithm() { + return digestAlgorithm; + } + + /** + * Set the Digest algorithm to use for Signature + * @param digestAlgorithm the Digest algorithm to use for Signature + */ + public void setDigestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/9e87ede2/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java index 16f1228..6ef99f2 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/SAMLTokenProvider.java @@ -397,7 +397,8 @@ public class SAMLTokenProvider implements TokenProvider { LOG.fine("Signing SAML Token"); boolean useKeyValue = signatureProperties.isUseKeyValue(); assertion.signAssertion( - alias, password, signatureCrypto, useKeyValue, c14nAlgorithm, signatureAlgorithm + alias, password, signatureCrypto, useKeyValue, c14nAlgorithm, signatureAlgorithm, + signatureProperties.getDigestAlgorithm() ); } http://git-wip-us.apache.org/repos/asf/cxf/blob/9e87ede2/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java index 28b731b..5dd8f52 100644 --- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java +++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/operation/IssueSamlUnitTest.java @@ -32,7 +32,6 @@ import javax.xml.namespace.QName; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; - import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.jaxws.context.WebServiceContextImpl; import org.apache.cxf.jaxws.context.WrappedMessageContext; @@ -972,6 +971,97 @@ public class IssueSamlUnitTest extends org.junit.Assert { } /** + * Test to successfully issue a Saml 2 token using a specified Signature Algorithm. + */ + @org.junit.Test + public void testIssueSaml2DifferentSignatureToken() throws Exception { + if (!TestUtils.checkUnrestrictedPoliciesInstalled()) { + return; + } + + 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> acceptedSignatureAlgorithms = new ArrayList<String>(); + String signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; + acceptedSignatureAlgorithms.add(signatureAlgorithm); + acceptedSignatureAlgorithms.add(WSConstants.RSA_SHA1); + sigProperties.setAcceptedSignatureAlgorithms(acceptedSignatureAlgorithms); + 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> signatureAlg = + new JAXBElement<String>( + QNameConstants.SIGNATURE_ALGORITHM, String.class, signatureAlgorithm + ); + request.getAny().add(signatureAlg); + + // 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(signatureAlgorithm)); + } + + /** * Test to UseKey validation */ @org.junit.Test http://git-wip-us.apache.org/repos/asf/cxf/blob/9e87ede2/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java index 07c3b16..38191ab 100644 --- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java +++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/token/provider/SAMLProviderKeyTypeTest.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Properties; import org.w3c.dom.Element; - import org.apache.cxf.jaxws.context.WebServiceContextImpl; import org.apache.cxf.jaxws.context.WrappedMessageContext; import org.apache.cxf.message.MessageImpl; @@ -33,6 +32,7 @@ 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; import org.apache.cxf.sts.request.BinarySecret; import org.apache.cxf.sts.request.Entropy; import org.apache.cxf.sts.request.KeyRequirements; @@ -494,6 +494,72 @@ public class SAMLProviderKeyTypeTest extends org.junit.Assert { } /** + * Create a default Saml2 Bearer Assertion using a different Signature algorithm + */ + @org.junit.Test + public void testDefaultSaml2BearerDifferentSignatureAlgorithm() throws Exception { + if (!TestUtils.checkUnrestrictedPoliciesInstalled()) { + return; + } + + TokenProvider samlTokenProvider = new SAMLTokenProvider(); + TokenProviderParameters providerParameters = + createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE, STSConstants.BEARER_KEY_KEYTYPE); + KeyRequirements keyRequirements = providerParameters.getKeyRequirements(); + + String signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; + keyRequirements.setSignatureAlgorithm(signatureAlgorithm); + + // This will fail as the requested signature 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(signatureAlgorithm)); + assertTrue(tokenString.contains(WSConstants.RSA_SHA1)); + + STSPropertiesMBean stsProperties = providerParameters.getStsProperties(); + SignatureProperties sigProperties = new SignatureProperties(); + List<String> acceptedSignatureAlgorithms = new ArrayList<String>(); + acceptedSignatureAlgorithms.add(signatureAlgorithm); + acceptedSignatureAlgorithms.add(WSConstants.RSA_SHA1); + sigProperties.setAcceptedSignatureAlgorithms(acceptedSignatureAlgorithms); + stsProperties.setSignatureProperties(sigProperties); + + // This will succeed as the requested signature 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(signatureAlgorithm)); + } + + /** + * Create a default Saml2 Bearer Assertion using a different Signature Digest algorithm + */ + @org.junit.Test + public void testDefaultSaml2BearerDifferentSignatureDigestAlgorithm() throws Exception { + TokenProvider samlTokenProvider = new SAMLTokenProvider(); + TokenProviderParameters providerParameters = + createProviderParameters(WSConstants.WSS_SAML2_TOKEN_TYPE, STSConstants.BEARER_KEY_KEYTYPE); + SignatureProperties signatureProperties = + providerParameters.getStsProperties().getSignatureProperties(); + signatureProperties.setDigestAlgorithm(WSConstants.SHA256); + + TokenProviderResponse providerResponse = samlTokenProvider.createToken(providerParameters); + assertTrue(providerResponse != null); + assertTrue(providerResponse.getToken() != null && providerResponse.getTokenId() != null); + + Element token = providerResponse.getToken(); + String tokenString = DOM2Writer.nodeToString(token); + assertTrue(tokenString.contains(WSConstants.SHA256)); + } + + /** * Create a default Saml2 Symmetric Key Assertion using EncryptWith Algorithms. */ @org.junit.Test
