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 2010/02/18 17:26:19 UTC

Re: Using HTTPS in camel-http when remote side has self-signed cert

Hello,
I would like to monitor an HTTPS endpoint and connect to it in two different
ways.  I would like to connect to it in one route using HTTPS w/ client
certificates and in another route using HTTPS using server certificate only. 
The reason for doing this is because all the endpoints I am monitoring
should require client certificates and connecting to the endpoint with HTTPS
with server cert only will produce an alert and I can inform the owner that
their security configuration is wrong.

I tried created two separate beans that implement HttpClientConfigurer.  One
of them will trust all certs:


	     public void configureHttpClient(HttpClient client) {
	         // register the customer SSLFactory
	         ProtocolSocketFactory easy = null;
			try {
				easy = new EasySSLProtocolSocketFactory();
			} catch (GeneralSecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	         Protocol protocol = new Protocol("https", easy, 17444);
	         Protocol.registerProtocol("https", protocol);

	     }


The other one will have use a keystore/truststore to connect to the
endpoint:


	public void configureHttpClient(HttpClient arg0) {
		Protocol authhttps = null;
		try {
			authhttps = new Protocol("https", new AuthSSLProtocolSocketFactory(
					  new URL("file:" + keystoreLocation), keystorePassword,
					  new URL("file:" + truststoreLocation), truststorePassword), 17444);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (GeneralSecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		Protocol.registerProtocol("https", authhttps);		
	}

Then in spring, I declare beans for these HTTPS configs:

	<bean id="myHttpClientConfigurerCerts"
		class="gov.wisconsin.wijis.camel.https.WijisHttpClientConfigurerCerts">
			<property name="keystoreLocation" value="${KEYSTORE_LOCATION}"/>
		    <property name="keystorePassword" value="${KEYSTORE_PASSWORD}"/>
			<property name="truststoreLocation" value="${TRUSTSTORE_LOCATION}"/>
			<property name="truststorePassword" value="${TRUSTSTORE_PASSWORD}"/>
	</bean>
	
	<bean id="myHttpClientConfigurerTrustAllCACerts"
class="gov.wisconsin.wijis.camel.https.WijisHttpClientConfigurerTrustAllCACerts"
/>


I refer to these endpoints in a producer template using java code like this
and passing in the http configuration using the registry:

String url =
"http://someURL.com/?httpClientConfigurerRef=myHttpClientConfigurerCerts";
template.sendBodyAndHeader(url, null, Exchange.HTTP_METHOD, "GET");

or

String url =
"http://someURL.com/?httpClientConfigurerRef=myHttpClientConfigurerTrustAllCACerts";
template.sendBodyAndHeader(url, null, Exchange.HTTP_METHOD, "GET");


However the problem I have is that the endpoint which will 'TrustAllCACerts'
is sending using the 'myHttpClientConfigurerCerts' configuration.  This
happens very randomly.  Sometimes it will use the TrustAllCerts
configuration and other times it will use the other one.

I think the answer to my problems might be CompositeHttpConfigurer but I
don't see any examples on how to use that.

Does anyone have any ideas?  

Thanks,
yogesh




willem.jiang wrote:
> 
> Hi,
> 
> You can do some customer modification on the HttpClient through the 
> CamelHttpClientConfigurer interface.
> 
> public class AcceptSelfSignCertHttpClientConfigure implements 
> HttpClientConfigurer {
> 
>      public void configureHttpClient(HttpClient client) {
>          // register the customer SSLFactory
>          ProtocolSocketFactory easy = new EasySSLProtocolSocketFactory();
>          Protocol protocol = new Protocol("https", easy, 8443);
>          Protocol.registerProtocol("https", protocol);
> 
>      }
> }
> 
> And configure the configure through the HTTP endpoint URI.
> 
> If you has another http client configuration , you can use the 
> CompositeHttpConfigurer[1] to hold these configuration.
> 
> [1] 
> https://svn.apache.org/repos/asf/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/CompositeHttpConfigurer.java
> 
> Willem
> 
> 
> Scott Parkerson wrote:
>> I'm trying to use Camel's HTTP component to send a POST request to a
>> web service using HTTPS. When I attempt to connect, I get the
>> following exception:
>> 
>> org.apache.camel.RuntimeCamelException:
>> javax.net.ssl.SSLHandshakeException:
>> sun.security.validator.ValidatorException: PKIX path building failed:
>> sun.security.provider.certpath.SunCertPathBuilderException: unable to
>> find valid certification path to requested target
>>         at
>> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:850)
>>         at
>> org.apache.camel.impl.ProducerCache.send(ProducerCache.java:138)
>>         at
>> org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:101)
>>         at
>> org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:105)
>>         at
>> org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:121)
>>         at
>> org.apache.camel.impl.DefaultProducerTemplate.requestBody(DefaultProducerTemplate.java:201)
>> [etc.]
>> 
>> I'm pretty sure that this is because the remote side is using a
>> self-signed certificate.
>> 
>> The question is: is there a good way to replace the behavior SSL
>> factory used by the Commons HTTPClient inside of the camel-http
>> component to make it accept self-signed certificates? I see that the
>> docs mention that you can provide a class that extends
>> CamelHttpClientConfigurer and configure the endpoint to use a
>> reference to that bean.
>> 
>> Ideas?
>> 
>> --sgp
>> cf. http://www.smerpology.org/
>> 
> 
> 
> 

-- 
View this message in context: http://old.nabble.com/Using-HTTPS-in-camel-http-when-remote-side-has-self-signed-cert-tp25916878p27639063.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Using HTTPS in camel-http when remote side has self-signed cert

Posted by Christian Mueller <ch...@gmail.com>.
Yogesh,
if you have a look on org.apache.commons.httpclient.protocol.Protocol, you
will see, that registerProtocol stores the protocol in a HashMap. Using the
same key "https" overrides the first registered protocol:

public class Protocol {
    private static final Map PROTOCOLS = Collections.synchronizedMap(new
HashMap());

    public static void registerProtocol(String id, Protocol protocol) {
        if (id == null) {
            throw new IllegalArgumentException("id is null");
        }
        if (protocol == null) {
            throw new IllegalArgumentException("protocol is null");
        }

        PROTOCOLS.put(id, protocol);
    }
}

Regards,
Christian
-- 
View this message in context: http://old.nabble.com/Using-HTTPS-in-camel-http-when-remote-side-has-self-signed-cert-tp25916878p27694404.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Using HTTPS in camel-http when remote side has self-signed cert

Posted by ychawla <pr...@yahoo.com>.
One way to solve this issue is to run two seperate instances of Camel and
have the two different connection methods isolated in their own JVMs or
webapps.  Any other ideas?



ychawla wrote:
> 
> Hello,
> I would like to monitor an HTTPS endpoint and connect to it in two
> different ways.  I would like to connect to it in one route using HTTPS w/
> client certificates and in another route using HTTPS using server
> certificate only.  The reason for doing this is because all the endpoints
> I am monitoring should require client certificates and connecting to the
> endpoint with HTTPS with server cert only will produce an alert and I can
> inform the owner that their security configuration is wrong.
> 
> I tried created two separate beans that implement HttpClientConfigurer. 
> One of them will trust all certs:
> 
> 
> 	     public void configureHttpClient(HttpClient client) {
> 	         // register the customer SSLFactory
> 	         ProtocolSocketFactory easy = null;
> 			try {
> 				easy = new EasySSLProtocolSocketFactory();
> 			} catch (GeneralSecurityException e) {
> 				// TODO Auto-generated catch block
> 				e.printStackTrace();
> 			} catch (IOException e) {
> 				// TODO Auto-generated catch block
> 				e.printStackTrace();
> 			}
> 	         Protocol protocol = new Protocol("https", easy, 17444);
> 	         Protocol.registerProtocol("https", protocol);
> 
> 	     }
> 
> 
> The other one will have use a keystore/truststore to connect to the
> endpoint:
> 
> 
> 	public void configureHttpClient(HttpClient arg0) {
> 		Protocol authhttps = null;
> 		try {
> 			authhttps = new Protocol("https", new AuthSSLProtocolSocketFactory(
> 					  new URL("file:" + keystoreLocation), keystorePassword,
> 					  new URL("file:" + truststoreLocation), truststorePassword), 17444);
> 		} catch (MalformedURLException e) {
> 			// TODO Auto-generated catch block
> 			e.printStackTrace();
> 		} catch (GeneralSecurityException e) {
> 			// TODO Auto-generated catch block
> 			e.printStackTrace();
> 		} catch (IOException e) {
> 			// TODO Auto-generated catch block
> 			e.printStackTrace();
> 		}
> 
> 		Protocol.registerProtocol("https", authhttps);		
> 	}
> 
> Then in spring, I declare beans for these HTTPS configs:
> 
> 	<bean id="myHttpClientConfigurerCerts"
> 		class="gov.wisconsin.wijis.camel.https.WijisHttpClientConfigurerCerts">
> 			<property name="keystoreLocation" value="${KEYSTORE_LOCATION}"/>
> 		    <property name="keystorePassword" value="${KEYSTORE_PASSWORD}"/>
> 			<property name="truststoreLocation" value="${TRUSTSTORE_LOCATION}"/>
> 			<property name="truststorePassword" value="${TRUSTSTORE_PASSWORD}"/>
> 	</bean>
> 	
> 	<bean id="myHttpClientConfigurerTrustAllCACerts"
> class="gov.wisconsin.wijis.camel.https.WijisHttpClientConfigurerTrustAllCACerts"
> />
> 
> 
> I refer to these endpoints in a producer template using java code like
> this and passing in the http configuration using the registry:
> 
> String url =
> "http://someURL.com/?httpClientConfigurerRef=myHttpClientConfigurerCerts";
> template.sendBodyAndHeader(url, null, Exchange.HTTP_METHOD, "GET");
> 
> or
> 
> String url =
> "http://someURL.com/?httpClientConfigurerRef=myHttpClientConfigurerTrustAllCACerts";
> template.sendBodyAndHeader(url, null, Exchange.HTTP_METHOD, "GET");
> 
> 
> However the problem I have is that the endpoint which will
> 'TrustAllCACerts' is sending using the 'myHttpClientConfigurerCerts'
> configuration.  This happens very randomly.  Sometimes it will use the
> TrustAllCerts configuration and other times it will use the other one.
> 
> I think the answer to my problems might be CompositeHttpConfigurer but I
> don't see any examples on how to use that.
> 
> Does anyone have any ideas?  
> 
> Thanks,
> yogesh
> 
> 
> 
> 
> willem.jiang wrote:
>> 
>> Hi,
>> 
>> You can do some customer modification on the HttpClient through the 
>> CamelHttpClientConfigurer interface.
>> 
>> public class AcceptSelfSignCertHttpClientConfigure implements 
>> HttpClientConfigurer {
>> 
>>      public void configureHttpClient(HttpClient client) {
>>          // register the customer SSLFactory
>>          ProtocolSocketFactory easy = new EasySSLProtocolSocketFactory();
>>          Protocol protocol = new Protocol("https", easy, 8443);
>>          Protocol.registerProtocol("https", protocol);
>> 
>>      }
>> }
>> 
>> And configure the configure through the HTTP endpoint URI.
>> 
>> If you has another http client configuration , you can use the 
>> CompositeHttpConfigurer[1] to hold these configuration.
>> 
>> [1] 
>> https://svn.apache.org/repos/asf/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/CompositeHttpConfigurer.java
>> 
>> Willem
>> 
>> 
>> Scott Parkerson wrote:
>>> I'm trying to use Camel's HTTP component to send a POST request to a
>>> web service using HTTPS. When I attempt to connect, I get the
>>> following exception:
>>> 
>>> org.apache.camel.RuntimeCamelException:
>>> javax.net.ssl.SSLHandshakeException:
>>> sun.security.validator.ValidatorException: PKIX path building failed:
>>> sun.security.provider.certpath.SunCertPathBuilderException: unable to
>>> find valid certification path to requested target
>>>         at
>>> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:850)
>>>         at
>>> org.apache.camel.impl.ProducerCache.send(ProducerCache.java:138)
>>>         at
>>> org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:101)
>>>         at
>>> org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:105)
>>>         at
>>> org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:121)
>>>         at
>>> org.apache.camel.impl.DefaultProducerTemplate.requestBody(DefaultProducerTemplate.java:201)
>>> [etc.]
>>> 
>>> I'm pretty sure that this is because the remote side is using a
>>> self-signed certificate.
>>> 
>>> The question is: is there a good way to replace the behavior SSL
>>> factory used by the Commons HTTPClient inside of the camel-http
>>> component to make it accept self-signed certificates? I see that the
>>> docs mention that you can provide a class that extends
>>> CamelHttpClientConfigurer and configure the endpoint to use a
>>> reference to that bean.
>>> 
>>> Ideas?
>>> 
>>> --sgp
>>> cf. http://www.smerpology.org/
>>> 
>> 
>> 
>> 
> 
> 

-- 
View this message in context: http://old.nabble.com/Using-HTTPS-in-camel-http-when-remote-side-has-self-signed-cert-tp25916878p27689918.html
Sent from the Camel - Users mailing list archive at Nabble.com.