[CXF-5664] - CXF STS does not support wst:Participants - Added some unit tests
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/eeee90c3 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/eeee90c3 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/eeee90c3 Branch: refs/heads/2.7.x-fixes Commit: eeee90c3e2e35c32a93a4f7b257d625bb2268d3a Parents: 4e7d439 Author: Colm O hEigeartaigh <[email protected]> Authored: Mon Apr 14 11:32:15 2014 +0100 Committer: Colm O hEigeartaigh <[email protected]> Committed: Mon Apr 14 11:39:00 2014 +0100 ---------------------------------------------------------------------- .../apache/cxf/sts/request/RequestParser.java | 5 +- .../provider/DefaultConditionsProvider.java | 21 +- .../cxf/sts/operation/IssueSamlUnitTest.java | 195 ++++++++++++++++++- 3 files changed, 204 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/eeee90c3/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java index e87f738..2406d66 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/request/RequestParser.java @@ -64,6 +64,7 @@ import org.apache.cxf.ws.security.sts.provider.model.ClaimsType; import org.apache.cxf.ws.security.sts.provider.model.EntropyType; import org.apache.cxf.ws.security.sts.provider.model.LifetimeType; import org.apache.cxf.ws.security.sts.provider.model.OnBehalfOfType; +import org.apache.cxf.ws.security.sts.provider.model.ParticipantType; import org.apache.cxf.ws.security.sts.provider.model.ParticipantsType; import org.apache.cxf.ws.security.sts.provider.model.RenewTargetType; import org.apache.cxf.ws.security.sts.provider.model.RenewingType; @@ -435,8 +436,8 @@ public class RequestParser { && !participantsType.getParticipant().isEmpty()) { List<Object> secondaryParticipants = new ArrayList<Object>(participantsType.getParticipant().size()); - for (Object object : participantsType.getParticipant()) { - secondaryParticipants.add(object); + for (ParticipantType secondaryParticipant : participantsType.getParticipant()) { + secondaryParticipants.add(secondaryParticipant.getAny()); } participants.setParticipants(secondaryParticipants); } http://git-wip-us.apache.org/repos/asf/cxf/blob/eeee90c3/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java index 297b4a4..b044869 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/token/provider/DefaultConditionsProvider.java @@ -277,20 +277,15 @@ public class DefaultConditionsProvider implements ConditionsProvider { * Extract an address from a Particpants EPR DOM element */ protected static String extractAddressFromParticipantsEPR(Element participants) { - if (participants != null) { - Element endpointRef = + if (participants != null && STSConstants.WSA_NS_05.equals(participants.getNamespaceURI()) + && "EndpointReference".equals(participants.getLocalName())) { + LOG.fine("Found EndpointReference element"); + Element address = DOMUtils.getFirstChildWithName( - participants, STSConstants.WSA_NS_05, "EndpointReference" - ); - if (endpointRef != null) { - LOG.fine("Found EndpointReference element"); - Element address = - DOMUtils.getFirstChildWithName( - endpointRef, STSConstants.WSA_NS_05, "Address"); - if (address != null) { - LOG.fine("Found address element"); - return address.getTextContent(); - } + participants, STSConstants.WSA_NS_05, "Address"); + if (address != null) { + LOG.fine("Found address element"); + return address.getTextContent(); } } LOG.fine("Participants element does not exist or could not be parsed"); http://git-wip-us.apache.org/repos/asf/cxf/blob/eeee90c3/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 1aa942a..3a3e1dd 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 @@ -52,6 +52,8 @@ import org.apache.cxf.sts.token.provider.TokenProvider; import org.apache.cxf.ws.security.sts.provider.STSException; import org.apache.cxf.ws.security.sts.provider.model.BinarySecretType; import org.apache.cxf.ws.security.sts.provider.model.EntropyType; +import org.apache.cxf.ws.security.sts.provider.model.ParticipantType; +import org.apache.cxf.ws.security.sts.provider.model.ParticipantsType; import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenCollectionType; import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseCollectionType; import org.apache.cxf.ws.security.sts.provider.model.RequestSecurityTokenResponseType; @@ -1166,6 +1168,190 @@ public class IssueSamlUnitTest extends org.junit.Assert { } + @org.junit.Test + public void testSaml1Participants() 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"); + issueOperation.setStsProperties(stsProperties); + + // Mock up a request + RequestSecurityTokenType request = new RequestSecurityTokenType(); + JAXBElement<String> tokenType = + new JAXBElement<String>( + QNameConstants.TOKEN_TYPE, String.class, WSConstants.WSS_SAML_TOKEN_TYPE + ); + request.getAny().add(tokenType); + request.getAny().add(createAppliesToElement("http://dummy-service.com/dummy")); + + // Add participants + String primaryParticipant = "http://primary.participant/"; + String secondaryParticipant = "http://secondary.participant/"; + + ParticipantType primary = new ParticipantType(); + Document doc = DOMUtils.newDocument(); + primary.setAny(createEndpointReference(doc, primaryParticipant)); + + ParticipantType secondary = new ParticipantType(); + secondary.setAny(createEndpointReference(doc, secondaryParticipant)); + + ParticipantsType participants = new ParticipantsType(); + participants.setPrimary(primary); + participants.getParticipant().add(secondary); + + JAXBElement<ParticipantsType> participantsType = + new JAXBElement<ParticipantsType>( + QNameConstants.PARTICIPANTS, ParticipantsType.class, participants + ); + request.getAny().add(participantsType); + + // 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(SAML1Constants.CONF_BEARER)); + assertTrue(tokenString.contains(primaryParticipant)); + assertTrue(tokenString.contains(secondaryParticipant)); + } + + @org.junit.Test + public void testSaml2Participants() 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"); + 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")); + + // Add participants + String primaryParticipant = "http://primary.participant/"; + String secondaryParticipant = "http://secondary.participant/"; + + ParticipantType primary = new ParticipantType(); + Document doc = DOMUtils.newDocument(); + primary.setAny(createEndpointReference(doc, primaryParticipant)); + + ParticipantType secondary = new ParticipantType(); + secondary.setAny(createEndpointReference(doc, secondaryParticipant)); + + ParticipantsType participants = new ParticipantsType(); + participants.setPrimary(primary); + participants.getParticipant().add(secondary); + + JAXBElement<ParticipantsType> participantsType = + new JAXBElement<ParticipantsType>( + QNameConstants.PARTICIPANTS, ParticipantsType.class, participants + ); + request.getAny().add(participantsType); + + // 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(primaryParticipant)); + assertTrue(tokenString.contains(secondaryParticipant)); + } + /* * Create a security context object */ @@ -1187,14 +1373,19 @@ public class IssueSamlUnitTest extends org.junit.Assert { Document doc = DOMUtils.createDocument(); Element appliesTo = doc.createElementNS(STSConstants.WSP_NS, "wsp:AppliesTo"); appliesTo.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsp", STSConstants.WSP_NS); + appliesTo.appendChild(createEndpointReference(doc, addressUrl)); + return appliesTo; + } + + private Element createEndpointReference(Document doc, String addressUrl) { Element endpointRef = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:EndpointReference"); endpointRef.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05); Element address = doc.createElementNS(STSConstants.WSA_NS_05, "wsa:Address"); address.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:wsa", STSConstants.WSA_NS_05); address.setTextContent(addressUrl); endpointRef.appendChild(address); - appliesTo.appendChild(endpointRef); - return appliesTo; + + return endpointRef; } /*
