Thanks a million Colm. I was able to subclass the STSClient and override the AbstractSTSClient issue method just as you described.
I just added the code I needed right before the final writer.writeEndElement() call. Thanks again! On Monday, February 9, 2015, Colm O hEigeartaigh <[email protected]> wrote: > Hi Will, > > What I would suggest you do here is to subclass the STSClient in CXF: > > > https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/STSClient.java;h=afdaaeaa092460c5cbccd3f9723660ded9f12e2b;hb=HEAD > > In particular, you want to override the "issue" method here: > > > https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=rt/ws/security/src/main/java/org/apache/cxf/ws/security/trust/AbstractSTSClient.java;h=4b4630e9d3fe0afab4496de0c7b0dd5df2fca292;hb=HEAD > > Just copy the existing method code + add in your own custom code at the > end. > > Colm. > > On Thu, Feb 5, 2015 at 8:06 PM, Will Warren <[email protected] > <javascript:;>> > wrote: > > > Hi there, I’m new to CXF and I’m trying to call a service that requires > > authentication via a separate STS (.NET based) that has some interesting > > requirements. I’m a bit stuck as to how I can accomplish what I need to > > accomplish. > > > > I've configured the service client to call out for the security token > > before invoking the main service and it works (it's trying to call the > > STS), but the STS is expecting some extra data to be provided in the > > RequestSecurityToken element. The STS's policy specifies that the > > RequestSecurityToken be encrypted and signed before being sent up and > > that's what's causing me the issues. The encryption and signing is > working, > > but I can't seem to modify the RST in the SOAP message before it gets > > encrypted/digested/signed. > > > > I made an Interceptor and tried it on all the different phases I could > > find, but none of them seem to get invoked between the > RequestSecurityToken > > being created and the encryption and signing taking place. I could make > > modifications to the final SOAP message, but the part I’m interested in > is > > encrypted inside a CipherData block by that point. > > > > Is there already a facility to add extra elements to the > > RequestSecurityToken? Or do I have to do something more custom? > > > > Here's what my RST looks like now before it gets encrypted: > > > > <wst:RequestSecurityToken xmlns:wst=" > > http://docs.oasis-open.org/ws-sx/ws-trust/200512"> > > <wst:RequestType> > > http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType> > > <wsp:AppliesTo xmlns:wsp="http://www.w3.org/ns/ws-policy"> > > <wsa:EndpointReference xmlns:wsa=" > > http://www.w3.org/2005/08/addressing"> > > <wsa:Address>http://localhost:9085/MyService</wsa:Address> > > </wsa:EndpointReference> > > </wsp:AppliesTo> > > <wst:TokenType> > > http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1 > > </wst:TokenType> > > <wst:KeyType> > > http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey > > </wst:KeyType> > > <wst:KeySize>192</wst:KeySize> > > <wst:Entropy> > > <wst:BinarySecret Type=" > > http://docs.oasis-open.org/ws-sx/ws-trust/200512/Nonce > > ">OlbfbuCUf3N2lNf9mhD03gfeMk0TfPI2nLWx8edlL5w=</wst:BinarySecret> > > </wst:Entropy> > > <wst:ComputedKeyAlgorithm> > > http://docs.oasis-open.org/ws-sx/ws-trust/200512/CK/PSHA1 > > </wst:ComputedKeyAlgorithm> > > <wst:Renewing/> > > </wst:RequestSecurityToken> > > > > Here’s what the service needs it to look like (see the added Credentials > > element near the end): > > > > <t:RequestSecurityToken xmlns:t=" > > http://schemas.xmlsoap.org/ws/2005/02/trust"> > > <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue > > </t:RequestType> > > <wsp:AppliesTo xmlns:wsp=" > http://schemas.xmlsoap.org/ws/2004/09/policy > > "> > > <EndpointReference xmlns="http://www.w3.org/2005/08/addressing"> > > <Address>http://localhost:9085/MyService</Address> > > </EndpointReference> > > </wsp:AppliesTo> > > <t:Entropy> > > <t:BinarySecret > u:Id="uuid-e2d08122-45ab-45cd-80d1-46de2306836b-1" > > Type="http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce" xmlns:u=" > > > http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd > > ">Ssex4V/175NCIOK1j4Mmbl47GiThOQMd</t:BinarySecret> > > </t:Entropy> > > <t:KeySize>192</t:KeySize> > > <t:TokenType> > > http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1 > > </t:TokenType> > > <t:KeyType>http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey > > </t:KeyType> > > <Credentials> > > <UserName type="string">username</UserName> > > <Password type="string">password</Password> > > </Credentials> > > <t:ComputedKeyAlgorithm> > > http://schemas.xmlsoap.org/ws/2005/02/trust/CK/PSHA1 > > </t:ComputedKeyAlgorithm> > > </t:RequestSecurityToken> > > > > And this is more or less my code - where would I alter the RST?: > > > > CXFBusFactory bf = new CXFBusFactory(); > > Bus bus = bf.createBus(); > > > > STSClient stsClient = new STSClient(bus); > > Map<String, Object> stsProperties = new HashMap<>(); > > > > stsProperties.put(SecurityConstants.ENCRYPT_CRYPTO, stsMerlin); > > stsProperties.put(SecurityConstants.SIGNATURE_CRYPTO, stsMerlin); > > stsProperties.put(SecurityConstants.IS_BSP_COMPLIANT, "false"); > > stsClient.setProperties(stsProperties); > > > > stsClient.setWsdlLocation(" > http://localhost:9999/SecurityTokenService?wsdl > > "); > > stsClient.setServiceName("{http://tempuri.org/}Service"); > > stsClient.setEndpointName("{http://tempuri.org/}Service_Port"); > > > > stsClient.setKeySize(192); > > > > stsClient.getInInterceptors().add(new LoggingInInterceptor()); > > stsClient.getOutInterceptors().add(new LoggingOutInterceptor()); > > > > stsClient.setTokenType(" > > http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1 > > "); > > stsClient.setSoap12(); > > > > // Set the STS Client on the bus > > bus.setProperty(SecurityConstants.STS_CLIENT, stsClient); > > > > BusFactory.setDefaultBus(bus); > > BusFactory.setThreadDefaultBus(bus); > > > > MyService myService = new MyService(); > > IMyService myServicePort = myService.getCustomBindingIMyService(); > > > > Map<String, Object> ctx = > > ((BindingProvider)myServicePort).getRequestContext(); > > ctx.put(SecurityConstants.ENCRYPT_CRYPTO, merlin); > > ctx.put(SecurityConstants.SIGNATURE_CRYPTO, merlin); > > ctx.put(SecurityConstants.IS_BSP_COMPLIANT, "false"); > > > > myServicePort.doSomething(); > > > > Any insights are greatly appreciated. > > > > Thanks > > Will > > > > > > -- > Colm O hEigeartaigh > > Talend Community Coder > http://coders.talend.com > -- *Will Warren* DIRECTOR, PLATFORM SECURITY *SceneDoc* 855.400.0948 x103 TOLL FREE 647.478.1964 DIRECT 905.932.5263 MOBILE *www.scenedoc.com <http://www.scenedoc.com/>* | LinkedIn <http://www.linkedin.com/company/scenedoc> | Twitter <https://twitter.com/scenedocinc> | Facebook <https://www.facebook.com/scenedoc> | Google+ <https://plus.google.com/+Scenedoc/>
