You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Will Warren <wi...@scenedoc.com> on 2015/02/05 21:06:58 UTC

Alter the RST before encrypting

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

Re: Alter the RST before encrypting

Posted by Will Warren <wi...@scenedoc.com>.
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 <co...@apache.org>
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 <will.warren@scenedoc.com
> <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/>

Re: Alter the RST before encrypting

Posted by Colm O hEigeartaigh <co...@apache.org>.
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 <wi...@scenedoc.com>
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