Https support for <int-http:outbound-gateway> - spring

I need to implement https support for <int-http:outbound-gateway>.
Following is the scenario:
There is <int-http:inbound-gateway> which accepts inbound url to Spring integration. The reply-channel of <int-http:inbound-gateway> and <int-http:outbound-gateway> are same. Based on the HeaderValueRouter, the inbound request is forwarded from request-channel of <int-http:inbound-gateway> to request channel of <int-http:inbound-gateway> . Now response is received from the outbound url and put in the reply-channel.
The url-expression of <int-http:outbound-gateway> is built from the MesssageHeader "http_requestUrl" attribute.
Now if I host the external app in https. What configuration I need to make in <int-http:inbound-gateway> to get the response in reply-channel

Actually there is nothing to do with Spring Integration for SSL. It is a responsibility of the underlying HTTP engine. And, to be honest, it even doesn't depend on the ClientHttpRequestFactory implementation for the RestTemplate.
You just need to have the server SSL certificate and place it to the trustStore. That's is if your target service requires only trusting - single-way SSL.
If you need mutual SSL, you need to generate the key and store it in the keyStore for your Java and share with the server the public part - certificate.
More info you can find in the Java SSL documentation.

Related

Secure API JAX-RS API with ssl certificate over Jetty Server

I have Jax-RS REST API with Jetty Server in my Java 8 application. I am new to securing the REST API.
I have .pem file (certificate) in some path.
I want to use this certificate to validate the incoming request API.
Can someone point me a working example that how to validate APIs with ssl certificate?
Is there any way that I can validate only single API and not all.
SSL/TLS based authentication of a client certificate occurs very early in the connections/conversation with an HTTP server.
In java it happens entirely within the JVMs SSLEngine layer.
Basically like this (simplified)
Client connects to port 443
Jetty accepts the connection
Jetty tests to see what kind of traffic it is
Jetty sees that it's encrypted and sends the traffic through the JVM SSLEngine layer.
TLS negotiates encryption (JVM code)
TLS negotiates client certificate (JVM code)
Connection is established (JVM code)
Jetty reads the decrypted traffic on the connection and starts to parse the request
Jetty creates the request object and dispatches to the web app.
Web app (your REST layer) now handles the request and produces a response.
By the time the request reaches your API the client certificate has already been verified / validated by the TLS layer.
You will only ever receive requests that satisfy that layer.
You have the optional feature SecureRequestCustomizer that will include Request attributes that contains information from TLS layer, by way of the JVM's post-negotiated TLS layer.

Spring Gateway Question on reverse proxying to TLS micro-services

I am currently working on a project where each micro-service has it's own tls certificate.
I am thinking of using spring gateway to address a cross concerns like csrf (using the double submit pattern).
I would like the gateway to validate the csrf before proxying to micro-services and to create a new csrf value after each response of micro-service and mutate the response to include new csrf values.
Since each micro-service (that the gateway is proxying to) has it's own tls certificate is it possible to read and mutate the request before and after sending it to the micro-services?
I guess I am a little confused on how the gateway would work if it does not have the certificate to read the request.
The gateway will establish it's own tls connection. After which the gateway will then apply it's filters then proxy to a micro-service establishing another tls connection. In this senario we will have 2 different tls connections (from client browser to gateway, from gateway to service).
In my senario, I had micro-services with self signed certificates. The gateway settings will need to include the public keys for each service to establish a tls connection (since it will not be able to validate the certificate from a certificate authority). Spring gateway allows us to do this within the application properties file
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem
Lastly, I was able to validate csrf value within the gateway before proxying to micro-services by creating a filter to do this. I have decided against changing the csrf value every request. For my use case I only needed to generate the csrf once for the user's session (I generated the csrf once after the user signs in).

Spring RestTemplate netflix loadblancer not configuring httpClient header Host

We have a complicated app based on Spring Cloud, Netflix Loadbalancer, to make calls between micro-services ms1<client>-->ms2<server>
We are using a restTemplate.exchange call to a URI hostname that is a Eureka Key for FQDN lookup.
This configuration works in other micro-services, in fact the the restTemplate bean works for a different component's micro-service call.
The receiving the rest call is Cloud Foundry Go-router which I believe is just a ngineX proxy server, the httpClient request should have the header variable set to "Host":"FQDN" this allows the proxy to route the request to the proper instance in the space.
PROBLEM:
httpClient from ms makes the call to the ms
CompletionException. cause: org.springframework.web.client.HttpClientErrorException: 404 NOT_FOUND
This is the response from the CF go-router (simple proxy server), the request never gets http--> the ms instance.
When the RestClient configures the request it sets the header "Host" as localhost:8090 or whatever the ms hostname is???
Discussion related Questions:
So apparently we have a configuration problem here.
Any advice on how the netflix ribbon loadbalancer client stuff sets the httpClient headers?
What package class interceptor does this magic?
What configuration variables effect this?
Code debugging indicates that netflix.client.SimpleVipAddressResolver is running.
We've traced the debug all the way to the Apache httpClient and it has the header Host set to the ms hostname, it's set to that value in the netflix httpClient wrapper too.
I tried to create a simple reference implementation of this, but can't.
Any recommendations on troubleshooting?
Where to look or read docs on what com.netflix package?
Using the Camden Spring. Using profiles,
From the memory debugging;
ClientClassName:com.netflix.niws.client.http.RestClient
VipAddressResolverClassName:com.netflix.client.SimpleVipAddressResolver
NIWSServerListClassName:com.netflix.loadbalancer.ConfigurationBasedServerList
NFLoadBalancerClassName:com.netflix.loadbalancer.ZoneAwareLoadBalancer
NFLoadBalancerRuleClassName:com.netflix.loadbalancer.AvailabilityFilteringRule
EnablePrimeConnections:false,
CustomSSLSocketFactoryClassName:null,
TrustStorePassword:null,
EnableConnectionPool:true,
listOfServers:,
OkToRetryOnAllOperations:false,
RequestIdHeaderName:null
Our suspicion is that some application.properties, .yml, or bootstrap.yml is being set or not being set some where in the scan path ???.
We had just upgrade the platform spring boot 1.3.x to 1.4.2.
The ms inbound controller had the annotation
#RequestHeader HttpHeaders httpHeaders
Which is what we attached into the restTemplate.execute as a parameter and eventually found it way to the rest-netflix-httpClient as the request headers being used to call the ms. The Go-Router on CF must be using that value to perform the proxying to the instance.
Apparently, somewhere in the upgrades, one of two things happen, either
A) boot Controller #RequestHeader in version 1.3.2 did not put header Host.
B) previous versions of spring Cloud-netflix-ribbon overwrote the Host httpHeader value with the Ribbon lookup.
Either way, there was no special interceptor.
Spring cloud netflix Eureka will take whatever httpHeaders you provide (even if that header is key:Host and use those values.

Access Https Rest Service using Spring RestTemplate (2 way SSL between client and server)

Can anybody provide me with a code sample to access rest service url secured with https using spring rest template.
I have the certificate(.pfx format) password and send cient side certificate to server. server side is used on the client side certificate and established the connection
I want to create a springboot application that work as 2 way SSL between client and server.
Thanks.
I created a sample Spring Boot application that demonstrates how to create a RestTemplate that is configured for SSL client authentication. The sample application acts as the server as well which requires SSL mutual authentication (to demonstrate usage via the test case). In practice, the RestTemplate bean would interact with an external service. Hope this helps.
https://github.com/steve-oakey/spring-boot-sample-clientauth
I should note that the most important part of the example is creating the SSLContext. There are plenty of ways to create the SSLContext, I chose a method that uses the SSLContextBuilder from the org.apache.httpcomponents:httpclient library. Other methods such as using the Java API directly, or setting the javax.net.ssl.* JVM properties would also work.

Adding authentication to outbound http requests

I have a rest web service that is implemented using spring boot starter web. This service acts as a client to another application that requires authentication to make calls to it.
Calls made from the client to the server are using org.springframework.web.client.RestTemplate.
Is there a way to come up with a solution to add authentication headers to outbound requests at one single point before they are sent out?
I don't want to add headers in each of the requests separately.
Javadoc for RestTemplate says:
This template uses a SimpleClientHttpRequestFactory and a
DefaultResponseErrorHandler as default strategies for creating HTTP
connections or handling HTTP errors, respectively. These defaults can
be overridden through
HttpAccessor.setRequestFactory(org.springframework.http.client.ClientHttpRequestFactory)
So I would take SimpleClientHttpRequestFactory and override its prepareConnection(..) method.

Resources