You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by ychawla <pr...@yahoo.com> on 2012/03/09 19:29:20 UTC

Dynamically set WSS4J interceptor properties

Hello All,
I am using Camel/CXF to implement WS-Security Requirements, specifically in
this case Signature Encrypt and Timestamp.  I used an example that Camel
distributed as a starting point and manually configured the WSS4J
interceptors.  

My issue is that my service will call maybe 10 or 20 services.  I don't want
to configure one Interceptor per service I am calling because the only thing
that is different is the encryptionUser.  This is the alias of the public
key you are using to encrypt the message.  Here is the WSS4J interceptor:

	
	<bean id="wss4jOutInterceptor"
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
		<constructor-arg>
			<map>
				<entry key="action" value="Signature Encrypt Timestamp" />
				<entry key="user" value="client-key" />
				<entry key="encryptionUser" value="server-1-cert" />
				<entry key="passwordCallbackRef">
					<ref bean="passwordCallbackBean" />
				</entry>
				<entry key="signatureKeyIdentifier" value="DirectReference" />
				<entry key="signatureParts"
value="{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body" />
				<entry key="passwordType" value="PasswordDigest" />
			</map>
		</constructor-arg>
	</bean>

Notice that encryptionUser would have to be different for all requests.  I
don't want to recreate this bean multiple times.  I did figure out a
workaround for the properties files for WSS4J.

I use a bean to set the request context and inject the values:

	<bean id="cryptoPropertiesMessageProcessor"
class="org.myPackage.CryptoPropertiesMessageProcessor">
		<property name="cryptoProvider"
value="org.apache.ws.security.components.crypto.Merlin"/>
		<property name="keystoreType" value="jks"/>
		
		<property name="signingKeystore" value="client.jks"/>
		<property name="signingKeystorePassword" value="password"/>
		<property name="signingKeystoreAlias" value="client-key"/>
		<property name="encryptionKeystore" value="serverTrustore.ts"/>
		<property name="encryptionKeystorePassword" value="password"/>
		<property name="encryptionKeystoreAlias">
			<map>
				<entry key="endpoint1" value="server-1-cert" />
				<entry key="endpoint2" value="server-2-cert" />
			</map>	
		</property>
	</bean>

I set the key to the map as a Camel Header that I set in the route and then
I can retrieve the alias.  See this simple bean:

	public void addCryptoProperties(Exchange exchange) throws Exception
	{
        Map<String, Object> requestContext = new HashMap<String, Object>();
        
        Properties cryptoPropertiesSignature = new Properties();
       
cryptoPropertiesSignature.put("org.apache.ws.security.crypto.provider",cryptoProvider);
       
cryptoPropertiesSignature.put("org.apache.ws.security.crypto.merlin.keystore.password",
signingKeystorePassword);
       
cryptoPropertiesSignature.put("org.apache.ws.security.crypto.merlin.file",signingKeystore);
       
cryptoPropertiesSignature.put("org.apache.ws.security.crypto.merlin.keystore.type",
keystoreType);
       
cryptoPropertiesSignature.put("org.apache.ws.security.crypto.merlin.keystore.alias",
signingKeystoreAlias);
        
        requestContext.put("cryptoPropertiesSignature",
cryptoPropertiesSignature);
        
        /** IMPORTANT, the below configuration will only work with WSS4J
1.6, you need to use 'SignaturePropRefId' for 1.5 **/
       
requestContext.put("signaturePropRefId","cryptoPropertiesSignature"); 

        Properties cryptoPropertiesEncryption = new Properties();
       
cryptoPropertiesEncryption.put("org.apache.ws.security.crypto.provider",cryptoProvider);
       
cryptoPropertiesEncryption.put("org.apache.ws.security.crypto.merlin.keystore.password",
encryptionKeystorePassword);
       
cryptoPropertiesEncryption.put("org.apache.ws.security.crypto.merlin.file",encryptionKeystore);
       
cryptoPropertiesEncryption.put("org.apache.ws.security.crypto.merlin.keystore.type",
keystoreType);
        
        String encryptionAliasEndpoint =
(String)exchange.getIn().getHeader("endpointEncryptionAlias");
        String encryptionAlias = null;
        
        if (StringUtils.isNotBlank(encryptionAliasEndpoint))
        {
        	encryptionAlias =
encryptionKeystoreAlias.get(encryptionAliasEndpoint);
        }	
        else
        {
        	throw new Exception("Camel Header endpointEncryptionAlias is not
set");
        }	
        
       
cryptoPropertiesEncryption.put("org.apache.ws.security.crypto.merlin.keystore.alias",
encryptionAlias);
        
        requestContext.put("cryptoPropertiesEncryption",
cryptoPropertiesEncryption);
       
requestContext.put(WSHandlerConstants.ENC_PROP_REF_ID,"cryptoPropertiesEncryption"); 

        exchange.getIn().setHeader(Client.REQUEST_CONTEXT , requestContext);
	}

Now I just need to figure out how to set the WSS4J properties dynamically in
Camel.

Any ideas?

Thanks,
yogesh

--
View this message in context: http://camel.465427.n5.nabble.com/Dynamically-set-WSS4J-interceptor-properties-tp5551391p5551391.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Dynamically set WSS4J interceptor properties

Posted by ychawla <pr...@yahoo.com>.
Another idea here is to set the scope to 'request' on the WSS4J interceptor
and override a method to set the encryption user.  Has anyone done that
before similar to this:

http://forum.springsource.org/showthread.php?81311-Configuring-WSS4J-Encrypt-for-multiple-clients-how

Thanks,
Yogesh

--
View this message in context: http://camel.465427.n5.nabble.com/Dynamically-set-WSS4J-interceptor-properties-tp5551391p5551678.html
Sent from the Camel - Users mailing list archive at Nabble.com.